#include #include #include #include #define SIMPLE_DEMO 0 #if defined SIMPLE_DEMO && SIMPLE_DEMO ==1 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Create a window const char* className = "OpenGLWindowClass"; const char* windowTitle = "OpenGL Window"; const int windowWidth = 800; const int windowHeight = 600; WNDCLASSEX wc = {}; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = _T("OpenGLWindowClass"); if (!RegisterClassEx(&wc)) { MessageBox(NULL, _T("Failed to register window class"), _T("Error"), MB_OK | MB_ICONERROR); return -1; } HWND hwnd = CreateWindowEx( 0, //窗口扩展风格 _T("OpenGLWindowClass"), //指向注册类名的指针 _T("OpenGL Window"), //指向窗口名称的指针 WS_OVERLAPPEDWINDOW, //窗口风格 CW_USEDEFAULT, //窗口水平位置 CW_USEDEFAULT, //窗口垂直位置 windowWidth, //窗口宽度 windowHeight, //窗口深度 NULL, //父窗口的句柄 NULL, //菜单的句柄或是子窗口的标识符 hInstance, //应用程序实例的句柄 NULL //指向窗口的创建数据 ); if (!hwnd) { MessageBox(NULL, _T("Failed to create window"), _T("Error"), MB_OK | MB_ICONERROR); return -1; } else { UpdateWindow(hwnd); ShowWindow(hwnd, SW_SHOW); } HDC hdc = GetDC(hwnd); // Set pixel format PIXELFORMATDESCRIPTOR pfd = {}; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 24; pfd.cStencilBits = 8; pfd.iLayerType = PFD_MAIN_PLANE; int pixelFormat = ChoosePixelFormat(hdc, &pfd); if (!SetPixelFormat(hdc, pixelFormat, &pfd)) { MessageBox(NULL, _T("Failed to set pixel format"), _T("Error"), MB_OK | MB_ICONERROR); return -1; } // Create and activate OpenGL context HGLRC hglrc = wglCreateContext(hdc); if (!wglMakeCurrent(hdc, hglrc)) { MessageBox(NULL, _T("Failed to make OpenGL context current"), _T("Error"), MB_OK | MB_ICONERROR); return -1; } MessageBoxA(0, (char*)glGetString(GL_VERSION), "OPENGL VERSION", 0); // Now you have an active OpenGL context // Main message loop MSG msg = {}; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // Clean up and exit wglMakeCurrent(NULL, NULL); wglDeleteContext(hglrc); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); return 0; } LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CLOSE: PostQuitMessage(0); return 0; case WM_DESTROY: return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); } #else // Sample code showing how to create a modern OpenGL window and rendering context on Win32. #include typedef HGLRC WINAPI wglCreateContextAttribsARB_type(HDC hdc, HGLRC hShareContext, const int* attribList); wglCreateContextAttribsARB_type* wglCreateContextAttribsARB; // See https://www.opengl.org/registry/specs/ARB/wgl_create_context.txt for all values #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 typedef BOOL WINAPI wglChoosePixelFormatARB_type(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats); wglChoosePixelFormatARB_type* wglChoosePixelFormatARB; // See https://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt for all values #define WGL_DRAW_TO_WINDOW_ARB 0x2001 #define WGL_ACCELERATION_ARB 0x2003 #define WGL_SUPPORT_OPENGL_ARB 0x2010 #define WGL_DOUBLE_BUFFER_ARB 0x2011 #define WGL_PIXEL_TYPE_ARB 0x2013 #define WGL_COLOR_BITS_ARB 0x2014 #define WGL_DEPTH_BITS_ARB 0x2022 #define WGL_STENCIL_BITS_ARB 0x2023 #define WGL_FULL_ACCELERATION_ARB 0x2027 #define WGL_TYPE_RGBA_ARB 0x202B static void fatal_error(const char* msg) { MessageBoxA(NULL, msg, "Error", MB_OK | MB_ICONEXCLAMATION); exit(EXIT_FAILURE); } static void init_opengl_extensions(void) { // Before we can load extensions, we need a dummy OpenGL context, created using a dummy window. // We use a dummy window because you can only set the pixel format for a window once. For the // real window, we want to use wglChoosePixelFormatARB (so we can potentially specify options // that aren't available in PIXELFORMATDESCRIPTOR), but we can't load and use that before we // have a context. WNDCLASSA window_class = {}; window_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; window_class.lpfnWndProc = DefWindowProcA; window_class.hInstance = GetModuleHandle(0); window_class.lpszClassName = "Dummy_WGL_djuasiodwa"; if (!RegisterClassA(&window_class)) { fatal_error("Failed to register dummy OpenGL window."); } HWND dummy_window = CreateWindowExA( 0, window_class.lpszClassName, "Dummy OpenGL Window", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, window_class.hInstance, 0); if (!dummy_window) { fatal_error("Failed to create dummy OpenGL window."); } HDC dummy_dc = GetDC(dummy_window); PIXELFORMATDESCRIPTOR pfd = {}; pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.iPixelType = PFD_TYPE_RGBA; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.cColorBits = 32; pfd.cAlphaBits = 8; pfd.iLayerType = PFD_MAIN_PLANE; pfd.cDepthBits = 24; pfd.cStencilBits = 8; int pixel_format = ChoosePixelFormat(dummy_dc, &pfd); if (!pixel_format) { fatal_error("Failed to find a suitable pixel format."); } if (!SetPixelFormat(dummy_dc, pixel_format, &pfd)) { fatal_error("Failed to set the pixel format."); } HGLRC dummy_context = wglCreateContext(dummy_dc); if (!dummy_context) { fatal_error("Failed to create a dummy OpenGL rendering context."); } if (!wglMakeCurrent(dummy_dc, dummy_context)) { fatal_error("Failed to activate dummy OpenGL rendering context."); } wglCreateContextAttribsARB = (wglCreateContextAttribsARB_type*)wglGetProcAddress("wglCreateContextAttribsARB"); wglChoosePixelFormatARB = (wglChoosePixelFormatARB_type*)wglGetProcAddress("wglChoosePixelFormatARB"); wglMakeCurrent(dummy_dc, 0); wglDeleteContext(dummy_context); ReleaseDC(dummy_window, dummy_dc); DestroyWindow(dummy_window); } static HGLRC init_opengl(HDC real_dc) { init_opengl_extensions(); // Now we can choose a pixel format the modern way, using wglChoosePixelFormatARB. int pixel_format_attribs[] = { WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, WGL_SUPPORT_OPENGL_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, WGL_COLOR_BITS_ARB, 32, WGL_DEPTH_BITS_ARB, 24, WGL_STENCIL_BITS_ARB, 8, 0 }; int pixel_format; UINT num_formats; wglChoosePixelFormatARB(real_dc, pixel_format_attribs, 0, 1, &pixel_format, &num_formats); if (!num_formats) { fatal_error("Failed to set the OpenGL 3.3 pixel format."); } PIXELFORMATDESCRIPTOR pfd; DescribePixelFormat(real_dc, pixel_format, sizeof(pfd), &pfd); if (!SetPixelFormat(real_dc, pixel_format, &pfd)) { fatal_error("Failed to set the OpenGL 3.3 pixel format."); } // Specify that we want to create an OpenGL 4.6 core profile context int gl33_attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, 6, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 0, }; HGLRC gl33_context = wglCreateContextAttribsARB(real_dc, 0, gl33_attribs); if (!gl33_context) { fatal_error("Failed to create OpenGL 3.3 context."); } if (!wglMakeCurrent(real_dc, gl33_context)) { fatal_error("Failed to activate OpenGL 3.3 rendering context."); } return gl33_context; } static LRESULT CALLBACK window_callback(HWND window, UINT msg, WPARAM wparam, LPARAM lparam) { LRESULT result = 0; switch (msg) { case WM_CLOSE: case WM_DESTROY: PostQuitMessage(0); break; default: result = DefWindowProcA(window, msg, wparam, lparam); break; } return result; } static HWND create_window(HINSTANCE inst) { WNDCLASSA window_class = {}; window_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; window_class.lpfnWndProc = window_callback; window_class.hInstance = inst; window_class.hCursor = LoadCursor(0, IDC_ARROW); window_class.hbrBackground = 0; window_class.lpszClassName = "WGL_fdjhsklf"; if (!RegisterClassA(&window_class)) { fatal_error("Failed to register window."); } // Specify a desired width and height, then adjust the rect so the window's client area will be // that size. RECT rect = { }; rect.right = 1024; rect.bottom = 576; DWORD window_style = WS_OVERLAPPEDWINDOW; AdjustWindowRect(&rect, window_style, false); HWND window = CreateWindowExA( 0, window_class.lpszClassName, "OpenGL", window_style, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, 0, 0, inst, 0); if (!window) { fatal_error("Failed to create window."); } return window; } int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd_line, int show) { HWND window = create_window(inst); HDC gldc = GetDC(window); HGLRC glrc = init_opengl(gldc); ShowWindow(window, show); UpdateWindow(window); bool running = true; while (running) { MSG msg; while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { running = false; } else { TranslateMessage(&msg); DispatchMessageA(&msg); } } glClearColor(1.0f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Do OpenGL rendering here SwapBuffers(gldc); } return 0; } #endif