DirectX11 example: further tweaks/massaging (-15 lines). Syncing example.

This commit is contained in:
ocornut 2014-11-30 17:26:44 +00:00
parent 7f804d3d64
commit 0e6f288a2f
3 changed files with 61 additions and 79 deletions

View File

@ -3,7 +3,7 @@
#include "../shared/stb_image.h" // for .png loading #include "../shared/stb_image.h" // for .png loading
#include "../../imgui.h" #include "../../imgui.h"
// DirectX // DirectX 11
#include <d3d11.h> #include <d3d11.h>
#include <d3dcompiler.h> #include <d3dcompiler.h>
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
@ -115,12 +115,12 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
} }
// Bind shader and vertex buffers // Bind shader and vertex buffers
g_pd3dDeviceImmediateContext->IASetInputLayout(g_pInputLayout);
unsigned int stride = sizeof(CUSTOMVERTEX); unsigned int stride = sizeof(CUSTOMVERTEX);
unsigned int offset = 0; unsigned int offset = 0;
g_pd3dDeviceImmediateContext->IASetInputLayout(g_pInputLayout);
g_pd3dDeviceImmediateContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); g_pd3dDeviceImmediateContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
g_pd3dDeviceImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); g_pd3dDeviceImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
g_pd3dDeviceImmediateContext->VSSetShader(g_pVertexShader, NULL, 0); g_pd3dDeviceImmediateContext->VSSetShader(g_pVertexShader, NULL, 0);
g_pd3dDeviceImmediateContext->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); g_pd3dDeviceImmediateContext->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
@ -130,8 +130,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
// Setup render state // Setup render state
const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f };
const UINT sampleMask = 0xffffffff; g_pd3dDeviceImmediateContext->OMSetBlendState(g_blendState, blendFactor, 0xffffffff);
g_pd3dDeviceImmediateContext->OMSetBlendState(g_blendState, blendFactor, sampleMask);
// Render command lists // Render command lists
int vtx_offset = 0; int vtx_offset = 0;
@ -155,7 +154,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
g_pd3dDeviceImmediateContext->VSSetShader(NULL, NULL, 0); g_pd3dDeviceImmediateContext->VSSetShader(NULL, NULL, 0);
} }
HRESULT InitD3D(HWND hWnd) HRESULT InitDeviceD3D(HWND hWnd)
{ {
// Setup swap chain // Setup swap chain
DXGI_SWAP_CHAIN_DESC sd; DXGI_SWAP_CHAIN_DESC sd;
@ -198,10 +197,7 @@ HRESULT InitD3D(HWND hWnd)
RSDesc.DepthClipEnable = TRUE; RSDesc.DepthClipEnable = TRUE;
RSDesc.ScissorEnable = TRUE; RSDesc.ScissorEnable = TRUE;
RSDesc.AntialiasedLineEnable = FALSE; RSDesc.AntialiasedLineEnable = FALSE;
if (sd.SampleDesc.Count > 1) RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
RSDesc.MultisampleEnable = TRUE;
else
RSDesc.MultisampleEnable = FALSE;
ID3D11RasterizerState* pRState = NULL; ID3D11RasterizerState* pRState = NULL;
g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState); g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
@ -224,18 +220,11 @@ HRESULT InitD3D(HWND hWnd)
// Create the vertex shader // Create the vertex shader
{ {
ID3D10Blob * pErrorBlob = NULL; D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &g_pVertexShaderBlob, NULL);
D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &g_pVertexShaderBlob, &pErrorBlob); if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
if (g_pVertexShaderBlob == NULL)
{
//const char* pError = (const char*)pErrorBlob->GetBufferPointer();
pErrorBlob->Release();
return E_FAIL; return E_FAIL;
}
if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK) if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK)
return E_FAIL; return E_FAIL;
if (pErrorBlob)
pErrorBlob->Release();
// Create the input layout // Create the input layout
D3D11_INPUT_ELEMENT_DESC localLayout[] = { D3D11_INPUT_ELEMENT_DESC localLayout[] = {
@ -261,18 +250,11 @@ HRESULT InitD3D(HWND hWnd)
// Create the pixel shader // Create the pixel shader
{ {
ID3D10Blob * pErrorBlob; D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &g_pPixelShaderBlob, NULL);
D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &g_pPixelShaderBlob, &pErrorBlob); if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
if (g_pPixelShaderBlob == NULL)
{
//const char* pError = (const char*)pErrorBlob->GetBufferPointer();
pErrorBlob->Release();
return E_FAIL; return E_FAIL;
}
if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK) if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK)
return E_FAIL; return E_FAIL;
if (pErrorBlob)
pErrorBlob->Release();
} }
// Create the blending setup // Create the blending setup
@ -294,14 +276,16 @@ HRESULT InitD3D(HWND hWnd)
return S_OK; return S_OK;
} }
void Cleanup() void CleanupDevice()
{ {
if (g_pd3dDeviceImmediateContext) g_pd3dDeviceImmediateContext->ClearState(); if (g_pd3dDeviceImmediateContext) g_pd3dDeviceImmediateContext->ClearState();
// InitImGui
if (g_pFontSampler) g_pFontSampler->Release(); if (g_pFontSampler) g_pFontSampler->Release();
if (g_pFontTextureView) g_pFontTextureView->Release(); if (g_pFontTextureView) g_pFontTextureView->Release();
if (g_pVB) g_pVB->Release(); if (g_pVB) g_pVB->Release();
// InitDeviceD3D
if (g_blendState) g_blendState->Release(); if (g_blendState) g_blendState->Release();
if (g_pPixelShader) g_pPixelShader->Release(); if (g_pPixelShader) g_pPixelShader->Release();
if (g_pPixelShaderBlob) g_pPixelShaderBlob->Release(); if (g_pPixelShaderBlob) g_pPixelShaderBlob->Release();
@ -346,7 +330,7 @@ LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
io.AddInputCharacter((unsigned short)wParam); io.AddInputCharacter((unsigned short)wParam);
return true; return true;
case WM_DESTROY: case WM_DESTROY:
Cleanup(); CleanupDevice();
PostQuitMessage(0); PostQuitMessage(0);
return 0; return 0;
} }
@ -357,12 +341,14 @@ void InitImGui()
{ {
RECT rect; RECT rect;
GetClientRect(hWnd, &rect); GetClientRect(hWnd, &rect);
int display_w = (int)(rect.right - rect.left);
int display_h = (int)(rect.bottom - rect.top);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); // Display size, in pixels. For clamping windows positions. io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable) io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable)
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime. io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = VK_UP; io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
@ -385,13 +371,11 @@ void InitImGui()
{ {
D3D11_BUFFER_DESC bufferDesc; D3D11_BUFFER_DESC bufferDesc;
memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC));
bufferDesc.Usage = D3D11_USAGE_DYNAMIC; bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.ByteWidth = 10000 * sizeof(CUSTOMVERTEX); bufferDesc.ByteWidth = 10000 * sizeof(CUSTOMVERTEX);
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bufferDesc.MiscFlags = 0; bufferDesc.MiscFlags = 0;
if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pVB) < 0) if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pVB) < 0)
{ {
IM_ASSERT(0); IM_ASSERT(0);
@ -428,7 +412,7 @@ void InitImGui()
subResource.SysMemSlicePitch = 0; subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
// create texture view // Create texture view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(srvDesc)); ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
@ -439,7 +423,7 @@ void InitImGui()
pTexture->Release(); pTexture->Release();
} }
// create texture sampler // Create texture sampler
{ {
D3D11_SAMPLER_DESC desc; D3D11_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc)); ZeroMemory(&desc, sizeof(desc));
@ -456,17 +440,17 @@ void InitImGui()
} }
INT64 ticks_per_second = 0; INT64 ticks_per_second = 0;
INT64 time = 0; INT64 last_time = 0;
void UpdateImGui() void UpdateImGui()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Setup timestep // Setup time step
INT64 current_time; INT64 current_time;
QueryPerformanceCounter((LARGE_INTEGER *)&current_time); QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
io.DeltaTime = (float)(current_time - time) / ticks_per_second; io.DeltaTime = (float)(current_time - last_time) / ticks_per_second;
time = current_time; last_time = current_time;
// Setup inputs // Setup inputs
// (we already got mouse position, buttons, wheel from the window message callback) // (we already got mouse position, buttons, wheel from the window message callback)
@ -495,12 +479,13 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second)) if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1; return 1;
if (!QueryPerformanceCounter((LARGE_INTEGER *)&time)) if (!QueryPerformanceCounter((LARGE_INTEGER *)&last_time))
return 1; return 1;
// Initialize Direct3D // Initialize Direct3D
if (InitD3D(hWnd) < 0) if (InitDeviceD3D(hWnd) < 0)
{ {
CleanupDevice();
UnregisterClass("ImGui Example", wc.hInstance); UnregisterClass("ImGui Example", wc.hInstance);
return 1; return 1;
} }

View File

@ -1,7 +1,7 @@
#include <windows.h> #include <windows.h>
#include "../../imgui.h" #include "../../imgui.h"
// DirectX // DirectX 9
#include <d3dx9.h> #include <d3dx9.h>
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#include <dinput.h> #include <dinput.h>
@ -103,7 +103,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
} }
} }
HRESULT InitD3D(HWND hWnd) HRESULT InitDeviceD3D(HWND hWnd)
{ {
if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION))) if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL; return E_FAIL;
@ -124,16 +124,15 @@ HRESULT InitD3D(HWND hWnd)
return S_OK; return S_OK;
} }
void Cleanup() void CleanupDevice()
{ {
if (g_pTexture != NULL) // InitImGui
g_pTexture->Release(); if (g_pVB) g_pVB->Release();
if (g_pd3dDevice != NULL) // InitDeviceD3D
g_pd3dDevice->Release(); if (g_pTexture) g_pTexture->Release();
if (g_pd3dDevice) g_pd3dDevice->Release();
if (g_pD3D != NULL) if (g_pD3D) g_pD3D->Release();
g_pD3D->Release();
} }
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
@ -167,7 +166,7 @@ LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
io.AddInputCharacter((unsigned short)wParam); io.AddInputCharacter((unsigned short)wParam);
return true; return true;
case WM_DESTROY: case WM_DESTROY:
Cleanup(); CleanupDevice();
PostQuitMessage(0); PostQuitMessage(0);
return 0; return 0;
} }
@ -178,12 +177,14 @@ void InitImGui()
{ {
RECT rect; RECT rect;
GetClientRect(hWnd, &rect); GetClientRect(hWnd, &rect);
int display_w = (int)(rect.right - rect.left);
int display_h = (int)(rect.bottom - rect.top);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); // Display size, in pixels. For clamping windows positions. io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable) io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable)
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime. io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = VK_UP; io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
@ -222,17 +223,17 @@ void InitImGui()
} }
INT64 ticks_per_second = 0; INT64 ticks_per_second = 0;
INT64 time = 0; INT64 last_time = 0;
void UpdateImGui() void UpdateImGui()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Setup timestep // Setup time step
INT64 current_time; INT64 current_time;
QueryPerformanceCounter((LARGE_INTEGER *)&current_time); QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
io.DeltaTime = (float)(current_time - time) / ticks_per_second; io.DeltaTime = (float)(current_time - last_time) / ticks_per_second;
time = current_time; last_time = current_time;
// Setup inputs // Setup inputs
// (we already got mouse position, buttons, wheel from the window message callback) // (we already got mouse position, buttons, wheel from the window message callback)
@ -261,14 +262,13 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second)) if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1; return 1;
if (!QueryPerformanceCounter((LARGE_INTEGER *)&time)) if (!QueryPerformanceCounter((LARGE_INTEGER *)&last_time))
return 1; return 1;
// Initialize Direct3D // Initialize Direct3D
if (InitD3D(hWnd) < 0) if (InitDeviceD3D(hWnd) < 0)
{ {
if (g_pVB) CleanupDevice();
g_pVB->Release();
UnregisterClass(L"ImGui Example", wc.hInstance); UnregisterClass(L"ImGui Example", wc.hInstance);
return 1; return 1;
} }
@ -347,9 +347,6 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
ImGui::Shutdown(); ImGui::Shutdown();
if (g_pVB)
g_pVB->Release();
UnregisterClass(L"ImGui Example", wc.hInstance); UnregisterClass(L"ImGui Example", wc.hInstance);
return 0; return 0;
} }

View File

@ -156,17 +156,17 @@ void InitGL()
void InitImGui() void InitImGui()
{ {
int w, h; int w, h;
int fb_w, fb_h; int display_w, display_h;
glfwGetWindowSize(window, &w, &h); glfwGetWindowSize(window, &w, &h);
glfwGetFramebufferSize(window, &fb_w, &fb_h); glfwGetFramebufferSize(window, &display_w, &display_h);
mousePosScale.x = (float)fb_w / w; // Some screens e.g. Retina display have framebuffer size != from window size, and mouse inputs are given in window/screen coordinates. mousePosScale.x = (float)display_w / w; // Some screens e.g. Retina display have framebuffer size != from window size, and mouse inputs are given in window/screen coordinates.
mousePosScale.y = (float)fb_h / h; mousePosScale.y = (float)display_h / h;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)fb_w, (float)fb_h); // Display size, in pixels. For clamping windows positions. io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable) io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable)
io.PixelCenterOffset = 0.0f; // Align OpenGL texels io.PixelCenterOffset = 0.0f; // Align OpenGL texels
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
@ -230,7 +230,7 @@ void UpdateImGui()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Setup timestep // Setup time step
static double time = 0.0f; static double time = 0.0f;
const double current_time = glfwGetTime(); const double current_time = glfwGetTime();
io.DeltaTime = (float)(current_time - time); io.DeltaTime = (float)(current_time - time);