步骤:
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 struc