Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenGL+Win32 Implementation Example #2022

Closed
rafaelkrause opened this issue Aug 16, 2018 · 9 comments
Closed

OpenGL+Win32 Implementation Example #2022

rafaelkrause opened this issue Aug 16, 2018 · 9 comments

Comments

@rafaelkrause
Copy link

rafaelkrause commented Aug 16, 2018

Hi,

Just to help users how Want to use Dear Imgui with Win32 + OpenGL.
Please keep free to move this to right place.

We use IMGUI version 1.63, with OpenGL and Win32 Implementation

Note: wglext.h is required

// =============================================================================
//                                  INCLUDES
// =============================================================================
#include <Windows.h>
#include <stdio.h>
#include "imgui.h"
#include "imgui_impl_win32.h"
#include "imgui_impl_opengl3.h"
#include "imgui_internal.h"
#include <GL/gl3w.h>  
#include <gl/GL.h>
#include "wglext.h"
#include <tchar.h>


// =============================================================================
//                                  DEFINES/MACROS
// =============================================================================

// =============================================================================
//                               GLOBAL VARIABLES
// =============================================================================
HGLRC   g_GLRenderContext;
HDC     g_HDCDeviceContext;
HWND    g_hwnd;
PFNWGLSWAPINTERVALEXTPROC       wglSwapIntervalEXT;
PFNWGLGETSWAPINTERVALEXTPROC    wglGetSwapIntervalEXT;
int     g_display_w = 800; 
int     g_display_h = 600;

// =============================================================================
//                             FOWARD DECLARATIONS
// =============================================================================
void CreateGlContext();
void SetCurrentContext();
bool SetSwapInterval(int interval); //0 - No Interval, 1 - Sync whit VSYNC, n - n times Sync with VSYNC
bool WGLExtensionSupported(const char *extension_name);
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);


// =============================================================================
//                            CORE MAIN FUNCTIONS
// =============================================================================
//
// Aplication Entry
//------------------------------------------------------------------------------
 int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow){
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	UNREFERENCED_PARAMETER(nCmdShow);

	WNDCLASS wc      = {0}; 
	wc.lpfnWndProc   = WndProc;
	wc.hInstance     = hInstance;
	wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
	wc.lpszClassName = "NCUI";
	wc.style = CS_OWNDC;
	if( !RegisterClass(&wc) )
		return 1;
	g_hwnd = CreateWindow(wc.lpszClassName,"teste",WS_OVERLAPPEDWINDOW|WS_VISIBLE,0,0,640,480,0,0,hInstance,0);

    // Show the window
    ShowWindow(g_hwnd, SW_SHOWDEFAULT);
    UpdateWindow(g_hwnd);

    //Prepare OpenGlContext
    CreateGlContext();
    SetSwapInterval(1);
    gl3wInit();

    // Setup Dear ImGui binding
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;

    //Init Win32
    ImGui_ImplWin32_Init(g_hwnd);
            
    //Init OpenGL Imgui Implementation
    // GL 3.0 + GLSL 130
    const char* glsl_version = "#version 130";
    ImGui_ImplOpenGL3_Init(glsl_version);

    //Set Window bg color
	ImVec4 clear_color = ImVec4(1.000F, 1.000F, 1.000F, 1.0F);

    // Setup style
    ImGui::StyleColorsClassic();

    // Main loop
    MSG msg;
    ZeroMemory(&msg, sizeof(msg));
    while (msg.message != WM_QUIT)
    {
        // Poll and handle messages (inputs, window resize, etc.)
        // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
        // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
        // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
        // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
        if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            continue;
        }

        // Start the Dear ImGui frame
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplWin32_NewFrame();
        ImGui::NewFrame();
        //show Main Window
        ImGui::ShowDemoWindow();
        // Rendering
        ImGui::Render();       
        wglMakeCurrent(g_HDCDeviceContext, g_GLRenderContext);
        glViewport(0, 0, g_display_w, g_display_h);                 //Display Size got from Resize Command
        glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        wglMakeCurrent(g_HDCDeviceContext, g_GLRenderContext);
        SwapBuffers(g_HDCDeviceContext);
         
    }

    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    wglDeleteContext(g_GLRenderContext);
    ImGui::DestroyContext();
    ImGui_ImplWin32_Shutdown();

    DestroyWindow(g_hwnd);
    UnregisterClass(_T("NCUI"), wc.hInstance);

	return 0;
}

extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
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 (wParam != SIZE_MINIMIZED)
        {
            g_display_w = (UINT)LOWORD(lParam);
            g_display_h = (UINT)HIWORD(lParam);
        }
       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 CreateGlContext(){

	PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,    //Flags
		PFD_TYPE_RGBA,        // The kind of framebuffer. RGBA or palette.
		32,                   // Colordepth of the framebuffer.
		0, 0, 0, 0, 0, 0,
		0,
		0,
		0,
		0, 0, 0, 0,
		24,                   // Number of bits for the depthbuffer
		8,                    // Number of bits for the stencilbuffer
		0,                    // Number of Aux buffers in the framebuffer.
		PFD_MAIN_PLANE,
		0,
		0, 0, 0
	};

	g_HDCDeviceContext = GetDC(g_hwnd);   

    int pixelFormal = ChoosePixelFormat(g_HDCDeviceContext, &pfd); 
    SetPixelFormat(g_HDCDeviceContext,pixelFormal, &pfd);
    g_GLRenderContext = wglCreateContext(g_HDCDeviceContext);
    wglMakeCurrent(g_HDCDeviceContext, g_GLRenderContext);       
}

bool SetSwapInterval(int interval){	
    if (WGLExtensionSupported("WGL_EXT_swap_control"))
    {
        // Extension is supported, init pointers.
        wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT");

        // this is another function from WGL_EXT_swap_control extension
        wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) wglGetProcAddress("wglGetSwapIntervalEXT");

        wglSwapIntervalEXT(interval);
        return true;
    }
    
    return false;

}

//Got from https://stackoverflow.com/questions/589064/how-to-enable-vertical-sync-in-opengl/589232
bool WGLExtensionSupported(const char *extension_name){
    // this is pointer to function which returns pointer to string with list of all wgl extensions
    PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglGetExtensionsStringEXT = NULL;

    // determine pointer to wglGetExtensionsStringEXT function
    _wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) wglGetProcAddress("wglGetExtensionsStringEXT");

    if (strstr(_wglGetExtensionsStringEXT(), extension_name) == NULL)
    {
        // string was not found
        return false;
    }

    // extension is supported
    return true;
}

image

@ice1000
Copy link
Contributor

ice1000 commented Aug 16, 2018

Could you please share your color style?

@ocornut
Copy link
Owner

ocornut commented Aug 16, 2018

Thank you @rafaelkrause. Will try at some point to provide a raw Win32 example and this will be useful. Also linking to #1553.

@rafaelkrause
Copy link
Author

@ice1000

Could you please share your color style?

This is the Default Imgui Color with a White Background Window.

See code

// Setup style
ImGui::StyleColorsClassic();

@ocornut
Copy link
Owner

ocornut commented Aug 16, 2018 via email

@rafaelkrause
Copy link
Author

I see, do you know Where I can fix it?

@eXtreames
Copy link

I use this method, everything is drawn perfectly, but Geforce Experience captures this window and records it. How to fix this behavior?

@OPstriker
Copy link

OPstriker commented Mar 25, 2022

Something I realized is that you haven't set up the DPI for High DPI screens.
Can be Done with:

SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);

And Oh Yeah, It works well...
image

@OPstriker
Copy link

I use this method, everything is drawn perfectly, but Geforce Experience captures this window and records it. How to fix this behavior?

Seems like a issue you need to fix with Geforce Experience, I maybe wrong.....

@ocornut
Copy link
Owner

ocornut commented Apr 19, 2023

Closed/solved, see #3218 (comment)

@ocornut ocornut closed this as completed Apr 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants