Windows API 搭建OpenGL窗口
程序员文章站
2022-04-08 23:09:01
步骤: 1、创建windows窗口,得到窗口句柄hwnd 2、获取该窗口的设备环境hDC(当然也可以获取其他的设备环境,但我们一般是在创建的窗口上绘制) 3、创建OpenGL绘制环境RC,这个只能从hDC创建 4、将hDC和RC绑定到当前的线程 注:RC表示OpenGL的绘制环境,所有的OpenGL ......
步骤:
1、创建windows窗口,得到窗口句柄hwnd
2、获取该窗口的设备环境hdc(当然也可以获取其他的设备环境,但我们一般是在创建的窗口上绘制)
3、创建opengl绘制环境rc,这个只能从hdc创建
4、将hdc和rc绑定到当前的线程
注:rc表示opengl的绘制环境,所有的opengl命令都会在rc这个绘制环境中作用,所以必须在rc绑定到当前线程之后才能调用opengl命令,否则运行出错,内存访问错误。
一般的笔刷绘制,在hdc下即可。
封装的窗口类如下:
glwindow.h
#pragma once #include <windows.h> #include <gl/glew.h> #include <iostream> class glcontext { public: glcontext(); ~glcontext(); void setup(hwnd,hdc); void setuppixelformat(hdc); private: hwnd hwnd; hdc hdc; hglrc hrc; int format; }; glcontext::glcontext() { this->hwnd = 0; this->hdc = 0; this->hrc = 0; this->format = 0; } glcontext::~glcontext() { } void glcontext::setuppixelformat(hdc hdc) { int pixelformat; pixelformatdescriptor pfd = { sizeof(pixelformatdescriptor), // size 1, // version pfd_support_opengl | // opengl window pfd_draw_to_window | // render to window pfd_doublebuffer, // support double-buffering pfd_type_rgba, // color type 32, // prefered color depth 0, 0, 0, 0, 0, 0, // color bits (ignored) 0, // no alpha buffer 0, // alpha bits (ignored) 0, // no accumulation buffer 0, 0, 0, 0, // accum bits (ignored) 16, // depth buffer 0, // no stencil buffer 0, // no auxiliary buffers pfd_main_plane, // main layer 0, // reserved 0, 0, 0, // no layer, visible, damage masks }; pixelformat = choosepixelformat(hdc, &pfd); setpixelformat(hdc, pixelformat, &pfd); } void glcontext::setup(hwnd hwnd, hdc hdc) { this->hwnd = hwnd; this->hdc = hdc; setuppixelformat(hdc); hrc = wglcreatecontext(hdc); wglmakecurrent(hdc, hrc); //initialize glew glewexperimental = gl_true; glewinit(); if (allocconsole()) { freopen("conout$", "w+t", stdout); freopen("conout$", "w+t", stderr); const glubyte* devise = glgetstring(gl_renderer); //返回一个渲染器标识符,通常是个硬件平台 const glubyte* str = glgetstring(gl_version); printf("opengl实现的版本号:%s\n", str); printf("硬件平台:%s\n", devise); } } lresult callback mainwindowproc(hwnd hwnd, uint umsg, wparam wparam, lparam lparam); class glwindow { public: glwindow(); ~glwindow(); void setup(hinstance, hinstance, lpstr, int); //lresult callback mainwindowproc(hwnd hwnd, uint umsg, wparam wparam, lparam lparam); void registerdisplayfunc(void (*display)()) { this->display = display; } void run(); private: void(*display)(); private: bool exiting = false; long windowwidth = 800; long windowheight = 600; long windowbits = 64; bool fullscreen = false; wndclassex windowclass; // window class hwnd hwnd; // window handle hdc hdc; msg msg; // message dword dwexstyle; // window extended style dword dwstyle; // window style rect windowrect; glcontext glcontext; }; glwindow::glwindow() {} glwindow::~glwindow() {} void glwindow::setup(hinstance hinstance, hinstance hprevinstance, lpstr lpcmdline, int nshowcmd) { windowrect.left = (long)0; // set left value to 0 windowrect.right = (long)windowwidth; // set right value to requested width windowrect.top = (long)0; // set top value to 0 windowrect.bottom = (long)windowheight; // set bottom value to requested height // fill out the window class structure windowclass.cbsize = sizeof(wndclassex); windowclass.style = cs_hredraw | cs_vredraw; windowclass.lpfnwndproc = mainwindowproc; //当窗体触发任何一个事件时,便会调用该函数 windowclass.cbclsextra = 0; windowclass.cbwndextra = 0; windowclass.hinstance = hinstance; windowclass.hicon = loadicon(null, idi_application); // default icon windowclass.hcursor = loadcursor(null, idc_arrow); // default arrow windowclass.hbrbackground = null; // don't need background windowclass.lpszmenuname = null; // no menu windowclass.lpszclassname = l"windows api"; windowclass.hiconsm = loadicon(null, idi_winlogo); // windows logo small icon // register the windows class if (!registerclassex(&windowclass)) { puts("register class failed"); } dwexstyle = ws_ex_appwindow | ws_ex_windowedge; // window extended style dwstyle = ws_overlappedwindow; // windows style adjustwindowrectex(&windowrect, dwstyle, false, dwexstyle); // adjust window to true requested size // class registered, so now create our window hwnd = createwindowex(null, // extended style l"windows api", // class name l"opengl", // app name dwstyle | ws_clipchildren | ws_clipsiblings, 0, 0, // x,y coordinate windowrect.right - windowrect.left, windowrect.bottom - windowrect.top, // width, height null, // handle to parent null, // handle to menu hinstance, // application instance null); // no extra params showwindow(hwnd, sw_show); // display the window updatewindow(hwnd); // update the window hdc = getdc(hwnd); glcontext.setup(hwnd,hdc); } lresult callback mainwindowproc(hwnd hwnd, uint umsg, wparam wparam, lparam lparam) { int height, width; // dispatch messages switch (umsg) { case wm_create: // window creation break; case wm_destroy: // window destroy case wm_quit: closewindow(hwnd); break; case wm_close: // windows is closing // deselect rendering context and delete it //wglmakecurrent(hdc, null); //wgldeletecontext(hrc); // send wm_quit to message queue postquitmessage(0); break; case wm_size: height = hiword(lparam); // retrieve width and height width = loword(lparam); break; case wm_activateapp: // activate app break; case wm_paint: // paint paintstruct ps; beginpaint(hwnd, &ps); endpaint(hwnd, &ps); break; case wm_lbuttondown: // left mouse button break; case wm_rbuttondown: // right mouse button break; case wm_mousemove: // mouse movement break; case wm_lbuttonup: // left button release break; case wm_rbuttonup: // right button release break; case wm_keyup: break; case wm_keydown: int fwkeys; lparam keydata; fwkeys = (int)wparam; // virtual-key code keydata = lparam; // key data switch (fwkeys) { case vk_escape: postquitmessage(0); break; default: break; } break; default: break; } return defwindowproc(hwnd, umsg, wparam, lparam); } void glwindow::run() { while (true) { (*display)(); swapbuffers(hdc); while (peekmessage(&msg, null, 0, 0, pm_noremove)) { if (!getmessage(&msg, null, 0, 0)) { exiting = true; break; } translatemessage(&msg); dispatchmessage(&msg); } } }
主函数调用代码示例:
#include <windows.h> #include <cameras/phc.h> #include "shader.h" #include "cube.h" #include "glwindow.h" redips::phc phc; glwindow window; shader* shader; cube* cube; void display() { cube->draw(*shader, phc); } void initialize(hinstance hinstance, hinstance hprevinstance, lpstr lpcmdline, int nshowcmd) { phc.lookat(redips::float3(0, 0, 200), redips::float3(0, 0, 0), redips::float3(0, 1, 0)); window.setup(hinstance, hprevinstance, lpcmdline, nshowcmd); window.registerdisplayfunc(display); shader = new shader("./joint.vert", "./joint.frag"); cube = new cube(); } int winapi winmain(hinstance hinstance, hinstance hprevinstance, lpstr lpcmdline, int nshowcmd) { initialize(hinstance, hprevinstance, lpcmdline, nshowcmd); window.run(); return 1; }
运行:
上一篇: 新版PHP极大的增强功能和性能
推荐阅读
-
Python使用Windows API创建窗口示例【基于win32gui模块】
-
C# Windows API应用之基于FlashWindowEx实现窗口闪烁的方法
-
C# Windows API应用之基于GetDesktopWindow获得桌面所有窗口句柄的方法
-
Windows API 搭建OpenGL窗口
-
OpenGL Windows 窗口程序环境搭建
-
Python使用Windows API创建窗口示例【基于win32gui模块】
-
Python使用Windows API创建窗口示例
-
C# Windows API应用之基于FlashWindowEx实现窗口闪烁的方法
-
OpenGL Windows 窗口程序环境搭建
-
Windows API 搭建OpenGL窗口