步骤:

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 = ;
this->hDC = ;
this->hRC = ;
this->format = ;
}
GLContext::~GLContext()
{
} void GLContext::SetupPixelFormat(HDC hDC) {
int pixelFormat; PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size
, // version
PFD_SUPPORT_OPENGL | // OpenGL window
PFD_DRAW_TO_WINDOW | // render to window
PFD_DOUBLEBUFFER, // support double-buffering
PFD_TYPE_RGBA, // color type
, // prefered color depth
, , , , , , // color bits (ignored)
, // no alpha buffer
, // alpha bits (ignored)
, // no accumulation buffer
, , , , // accum bits (ignored)
, // depth buffer
, // no stencil buffer
, // no auxiliary buffers
PFD_MAIN_PLANE, // main layer
, // reserved
, , , // 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 = ;
long windowHeight = ;
long windowBits = ;
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); // Set Left Value To 0
windowRect.right = (long)windowWidth; // Set Right Value To Requested Width
windowRect.top = (long); // 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 = ;
windowClass.cbWndExtra = ;
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,
, , // 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();
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();
break;
default:
break;
}
break; default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
} void GLWindow::Run() {
while (true)
{
(*Display)();
SwapBuffers(hDC);
while (PeekMessage(&msg, NULL, , , PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, , ))
{
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(, , ), redips::float3(, , ), redips::float3(, , ));
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 ;
}

运行:

Windows API 搭建OpenGL窗口的更多相关文章

  1. 用C#调用Windows API向指定窗口发送按键消息 z

    用C#调用Windows API向指定窗口发送 一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.Interop ...

  2. 【转】用C#调用Windows API向指定窗口发送

    一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式 ...

  3. 用C#调用Windows API向指定窗口发送按键消息

    一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式 ...

  4. windows API下的模板缓冲(stencil buffer)

    在windows API搭建的OpenGL窗口中使用模板缓冲,需要在像素格式描述表中设置stencil buffer位宽为8,这样窗口会自动生成stencil buffer,然后可以在opengl环境 ...

  5. 善于 调用Windows API

    前一段时间看见别人做的一个自动填写信息并且点击登录的程序,觉得很有意思. 其实就是在程序中调用Windows的API,那么如何调用,下面就做个简单的介绍. 写的简单粗暴, 不喜轻喷. 0.首先引入名称 ...

  6. Windows MFC 两个OpenGL窗口显示与线程RC问题

    问题为:背景界面是一个OpenGL窗口(对话框),在其上弹出一个OpenGL窗口(模态对话框)时, 1.上方的OpenGL窗口能响应鼠标操作等并刷新: 2.当移动或放大缩小上方的OpenGL窗口时,其 ...

  7. [Modern OpenGL系列(二)]创建OpenGL窗口

    本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51295663 在博主的上一篇文章中已经介绍了OpenGL开发环境的搭建,本 ...

  8. Android学习——windows下搭建Cygwin环境

    在上一篇博文<Android学习——windows下搭建NDK_r9环境>中,我们详细的讲解了在windows下进行Android NDK开发环境的配置,我们也讲到了在NDk r7以后,我 ...

  9. OpenGL学习之windows下安装opengl的glut库

    OpenGL学习之windows下安装opengl的glut库 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装.  Windows环境下的GLUT下载地址:(大小约为15 ...

随机推荐

  1. 数据存储 --《高性能JavaScript》

    1.数据存储的方式 1.字面量 2.变量 3.数组项 4.对象成员 2.各自的性能特点 1.访问字面量和局部变量的速度最快,访问数组项和对象成员相对较慢 2.由于局部变量在作用域链的起始位置,因此访问 ...

  2. html使用代码大全

    <DIV style="FONT-SIZE: 9pt">1)贴图:<img src="图片地址">1)首行缩进2格:<p styl ...

  3. bash的pushd和popd

    1 pushd和popd是bash shell的builtin命令 2 pushd和popd维护了一个目录栈 pushd xxx就是将xxx放入目录栈顶. 目录栈顶就是当前的目录. 但是cd的话,会不 ...

  4. 区分虚拟机和machine simulator

    1 虚拟机和machine simulator的不同 虚拟机是让多个操作系统同时共用现有的硬件架构,它不会模拟新的硬件架构.qemu这样的模拟器是模拟新的硬件架构,这个架构和host不同.

  5. webdriver.close() quit() 批量kill进程 内存耗尽的解决办法

    问题现象: shell窗口卡,换IP的登录窗,不开: 猜测: 内存耗尽 spider_url,py driver = webdriver.PhantomJS( executable_path='/us ...

  6. Ruby map、each、select、inject、collect 、detect reference

    参考 https://ruby-china.org/topics/26718 map:(collect是map的别名函数) 对数组中每个元素进行表达式操作,原始数组不会被改变,返回执行表达式结果的新数 ...

  7. REST的本质,就是用户操作某个网络资源(具有独一无二的识别符URI),获得某种服务,也就是动词+资源(都是HTTP协议的一部分)

    REST的名称”表现状态转化”中,省略了主语.”表现”其实指的是资源的表现. 资源就是网络上的一个数据实体,或者说是一个具体信息.它可以是一段文本.一张图片.一首歌曲.一种服务.你可以用一个URI(统 ...

  8. NOIP2016总结

    Day1: T1:模拟: #include<iostream> #include<cstdio> #include<cstdlib> #include<cst ...

  9. maven实战(6)-- pom.xml的编写

    pom.xml中可以编写的东西确实挺多的,经常看到别人写的pom文件中出现了一些没见过plugin或properties等等,不知有何作用,其实很简单,只要参看maven的官方文档即可:http:// ...

  10. 安装YouCompleteMe时,编译依赖的python版本不对

    启动vim打开文件时出错: The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). YCM core library compile ...