Skip to content

Instantly share code, notes, and snippets.

@nathan130200
Last active October 14, 2020 01:36
Show Gist options
  • Save nathan130200/c4f24efe2cbc2145426f06e5a6e7aa83 to your computer and use it in GitHub Desktop.
Save nathan130200/c4f24efe2cbc2145426f06e5a6e7aa83 to your computer and use it in GitHub Desktop.
ImGUI Wrapper for POO style in C++
#include <vector>
#include <imgui.h>
#include <string>
#ifndef _CONTROL_H_
#define _CONTROL_H_
struct Control
{
protected:
bool m_shown;
std::string m_text;
public:
void Show(){
m_shown = true;
}
void Hide() {
m_shown = false;
}
void SetText(std::string text){
m_text = text;
}
std::string GetText() const {
return m_text;
}
virtual void Render() = 0;
};
typedef std::vector<Control> TControlList;
#define SIMPLE_CONTROL_IMPL(Name, RenderFunc) struct Name : public Control { void Render() RenderFunc };
SIMPLE_CONTROL_IMPL(Separator, {
ImGui::Separator();
});
SIMPLE_CONTROL_IMPL(SameLine, {
ImGui::SameLine();
});
#endif
#include "Main.h"
#include "Window.h"
TWindowList vWindows;
int main(int, char**)
{
// WNDCLASSEX wc = {
// sizeof(WNDCLASSEX),
// WndProc,
// CS_CLASSDC,
// 0L, GetModuleHandle(NULL), NULL,
// NULL, NULL, NULL, "FofWindowClass"
// };
vWindows.push_back(MakeWindow("Example 1"));
vWindows.push_back(MakeWindow("Example 2"));
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = &WndProc;
wc.cbClsExtra = CS_CLASSDC;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = "FofWindowClass";
RegisterClassEx(&wc);
HWND hwnd = CreateWindowEx(0, wc.lpszClassName, "FOF: GAME", WS_OVERLAPPEDWINDOW, 0, 0,
800, 600, NULL, NULL, wc.hInstance, NULL);
if(!CreateDeviceD3D(hwnd)) {
CleanupDeviceD3D();
UnregisterClassA(wc.lpszClassName, wc.hInstance);
MessageBoxW(NULL, L"Create Device D3d failed.", NULL, 0U);
return 1;
}
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigWindowsMoveFromTitleBarOnly = true;
ImGui::StyleColorsLight();
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX11_Init(pd3dDevice, pd3dDeviceContext);
MSG msg;
ZeroMemory(&msg, sizeof(msg));
ImVec4 fClearColor { 0, 0, 0, 0 };
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
// Call Render
Render();
ImGui::Render();
pd3dDeviceContext->OMSetRenderTargets(1, &pMainRenderTargetView, NULL);
pd3dDeviceContext->ClearRenderTargetView(pMainRenderTargetView, (float*)&fClearColor);
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
pSwapChain->Present(0, 0);
}
}
bool CreateDeviceD3D(HWND hWnd)
{
// Setup swap chain
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 2;
sd.BufferDesc.Width = 0;
sd.BufferDesc.Height = 0;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
UINT createDeviceFlags = 0;
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };
HRESULT code;
if ((code = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &pSwapChain, &pd3dDevice, &featureLevel, &pd3dDeviceContext)) != S_OK)
return false;
CreateRenderTarget();
return true;
}
void CleanupDeviceD3D()
{
CleanupRenderTarget();
if (pSwapChain) { pSwapChain->Release(); pSwapChain = NULL; }
if (pd3dDeviceContext) { pd3dDeviceContext->Release(); pd3dDeviceContext = NULL; }
if (pd3dDevice) { pd3dDevice->Release(); pd3dDevice = NULL; }
}
void CreateRenderTarget()
{
ID3D11Texture2D* pBackBuffer;
pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &pMainRenderTargetView);
pBackBuffer->Release();
}
void CleanupRenderTarget()
{
if (pMainRenderTargetView) {
pMainRenderTargetView->Release();
pMainRenderTargetView = NULL;
}
}
// Win32 message handler
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
return true;
switch (msg)
{
case WM_SIZE:
if (pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
{
CleanupRenderTarget();
pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0);
CreateRenderTarget();
}
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}
void Render() {
for(TWindowList::iterator it = vWindows.begin(); it != vWindows.end(); ++it){
((Window*)&*it)->Render();
}
}
#include <imgui.h>
#include <imgui_impl_win32.h>
#include <imgui_impl_dx11.h>
#include <d3d11.h>
#include <d3d11.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#include <tchar.h>
#include <Windows.h>
#pragma comment(lib, "d3d11.lib")
#ifndef _MAIN_H_
#define _MAIN_H_
static ID3D11Device* pd3dDevice = NULL;
static ID3D11DeviceContext* pd3dDeviceContext = NULL;
static IDXGISwapChain* pSwapChain = NULL;
static ID3D11RenderTargetView* pMainRenderTargetView = NULL;
bool CreateDeviceD3D(HWND hWnd);
void CleanupDeviceD3D();
void CreateRenderTarget();
void CleanupRenderTarget();
// Forward declare message handler from imgui_impl_win32.cpp
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void Render();
#endif
#include <imgui.h>
#include <vector>
#include "Control.h"
#ifndef _WINDOW_H_
#define _WINDOW_H_
struct Window : public Control
{
protected:
TControlList m_controls;
public:
void Render() override {
if(m_shown) {
ImGui::Begin(m_text.c_str());
for(TControlList::iterator it = m_controls.begin(); it != m_controls.end(); ++it){
((Control*)&*it)->Render();
}
ImGui::End();
}
}
const Control* GetControls() {
return m_controls.data();
}
size_t GetControlCount(){
return m_controls.size();
}
};
typedef std::vector<Window> TWindowList;
Window MakeWindow(std::string text){
Window w;
w.SetText(text);
w.Show();
return w;
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment