Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
373 lines (311 sloc) 7.96 KB
#include <windows.h>
#include <wingdi.h>
#include <stdio.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <wglarb.h>
#include <dwmapi.h>
LRESULT CALLBACK ViewProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
void display(HWND hWnd);
HGLRC hRC = NULL;
HMODULE hDwmAPI_DLL = NULL;
typedef HRESULT (WINAPI *procp_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND *);
procp_DwmEnableBlurBehindWindow impl_DwmEnableBlurBehindWindow = NULL;
typedef HRESULT (WINAPI *procp_DwmExtendFrameIntoClientArea)(HWND, MARGINS const*);
procp_DwmExtendFrameIntoClientArea impl_DwmExtendFrameIntoClientArea = NULL;
typedef HRESULT (WINAPI *procp_DwmGetColorizationColor)(DWORD*,BOOL*);
procp_DwmGetColorizationColor impl_DwmGetColorizationColor = NULL;
float bg_color[3];
int win_width;
int win_height;
HWND OpenGLWindowCreate(
LPCTSTR lpszWindowName,
LPCTSTR lpszClassName,
WNDPROC lpfnWndProc,
HINSTANCE hInstance,
DWORD dwStyle,
DWORD dwExStyle,
HWND hWndParent)
{
if(!hInstance) {
hInstance = GetModuleHandle(NULL);
}
WNDCLASS wc;
memset(&wc,0,sizeof(wc));
wc.hInstance = hInstance;
wc.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
/* Register DefWindowProc with each the intermediary and the
* proper window class. We're setting the window proc of the
* proper window to the user supplied window proc later so that
* we can use the default proper window class name if no class
* name was supplied by the user. It also allows to use the same
* user supplied window class name with multiple, different
* window functions. */
wc.lpfnWndProc = DefWindowProc;
/* register proper window class */
if( !lpszClassName ) {
return FALSE;
}
wc.lpszClassName = lpszClassName;
RegisterClass(&wc);
RECT rect;
if( hWndParent
&& (dwStyle & WS_CHILD) ) {
GetClientRect(hWndParent, &rect);
}
else {
rect.left =
rect.top =
rect.right =
rect.bottom = CW_USEDEFAULT;
}
HWND hWnd =
CreateWindowEx(
dwExStyle,
wc.lpszClassName,
lpszWindowName,
dwStyle,
rect.left,
rect.top,
rect.right,
rect.bottom,
hWndParent,
NULL,
hInstance,
NULL);
if(!hWnd) {
return NULL;
}
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)ViewProc);
HDC hDC = GetDC(hWnd);
if(!hDC) {
fprintf(stderr, "error retrieving proper DC\n");
DestroyWindow(hWnd);
return NULL;
}
int attribs[] = {
WGL_DRAW_TO_WINDOW_ARB, TRUE,
WGL_DOUBLE_BUFFER_ARB, TRUE,
WGL_SUPPORT_OPENGL_ARB, TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_TRANSPARENT_ARB, TRUE,
WGL_COLOR_BITS_ARB, 32,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
0, 0
};
INT iPF;
UINT num_formats_choosen;
if( !wglarb_ChoosePixelFormatARB(
hDC,
attribs,
NULL,
1,
&iPF,
&num_formats_choosen) ) {
fprintf(stderr, "error choosing proper pixel format\n");
return NULL;
}
if( !num_formats_choosen ) {
return NULL;
}
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
/* now this is a kludge; we need to pass something in the PIXELFORMATDESCRIPTOR
* to SetPixelFormat; it will be ignored, mostly. OTOH we want to send something
* sane, we're nice people after all - it doesn't hurt if this fails. */
DescribePixelFormat(hDC, iPF, sizeof(pfd), &pfd);
if( !SetPixelFormat(hDC, iPF, &pfd) ) {
fprintf(stderr, "error setting proper pixel format\n");
ReleaseDC(hWnd, hDC);
DestroyWindow(hWnd);
return NULL;
}
int context_attribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 2,
WGL_CONTEXT_MINOR_VERSION_ARB, 1,
0, 0
};
hRC = wglarb_CreateContextAttribsARB(hDC, NULL, context_attribs);
if(!hRC) {
ReleaseDC(hWnd, hDC);
DestroyWindow(hWnd);
return NULL;
}
ReleaseDC(hWnd, hDC);
if( hDwmAPI_DLL ) {
if( impl_DwmEnableBlurBehindWindow ) {
DWM_BLURBEHIND bb = {0};
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = TRUE;
bb.hRgnBlur = NULL;
impl_DwmEnableBlurBehindWindow(hWnd, &bb);
}
if( impl_DwmExtendFrameIntoClientArea ) {
MARGINS margins = {-1};
impl_DwmExtendFrameIntoClientArea(hWnd, &margins);
}
}
return hWnd;
fail_create_rc:
fail_set_pf:
fail_choose_pf:
ReleaseDC(hWnd, hDC);
fail_get_dc:
DestroyWindow(hWnd);
fail_create_wnd:
return NULL;
}
void OnOpenGLWindowDestroy()
{
wglMakeCurrent(NULL,NULL);
wglDeleteContext(hRC);
PostQuitMessage(0);
}
BOOL cursor_needs_setting = TRUE;
LRESULT CALLBACK ViewProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
DWORD bgcol;
BOOL opaque;
switch(uMsg)
{
case WM_CREATE:
case WM_DWMNCRENDERINGCHANGED:
if( impl_DwmGetColorizationColor ) {
impl_DwmGetColorizationColor(&bgcol, &opaque);
if( opaque ) {
bg_color[0] = (float)GetRValue(bgcol)/255.f;
bg_color[1] = (float)GetGValue(bgcol)/255.f;
bg_color[2] = (float)GetBValue(bgcol)/255.f;
}
else {
bg_color[0] = 0.f;
bg_color[1] = 0.f;
bg_color[2] = 0.f;
}
}
break;
case WM_MOUSELEAVE:
cursor_needs_setting = TRUE;
break;
case WM_MOUSEMOVE:
if( cursor_needs_setting ) {
SetClassLongPtr(hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor(NULL, IDC_ARROW));
cursor_needs_setting = FALSE;
}
break;
case WM_DESTROY:
OnOpenGLWindowDestroy();
break;
case WM_PAINT:
display(hWnd);
break;
default:
break;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
void display(HWND hWnd)
{
HDC hDC = GetDC(hWnd);
RECT rect;
GetClientRect(hWnd, &rect);
wglMakeCurrent(hDC, hRC);
float const ratio = (float)rect.right/(float)rect.bottom;
glViewport(
0,
0,
rect.right,
rect.bottom);
glClearColor(
bg_color[0],
bg_color[1],
bg_color[2],
0.);
glClearDepth(1.);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-ratio, ratio, -1., 1., -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float const cos60 = cosf(M_PI*60./180.);
float const sin60 = sinf(M_PI*60./180.);
GLfloat const triangle[] = {
-1., -sin60, 1., 0., 0.,
1., -sin60, 0., 1., 0.,
0., sin60, 0., 0., 1.
};
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*5, &triangle[0]);
glColorPointer( 3, GL_FLOAT, sizeof(GLfloat)*5, &triangle[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
SwapBuffers(hDC);
glFinish();
wglMakeCurrent(NULL, NULL);
ReleaseDC(hWnd, hDC);
}
#if 1
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
#else
int main(int argc, char *argv[])
{
HINSTANCE hInstance = GetModuleHandle(NULL);
#endif
MSG msg;
BOOL bRet;
OSVERSIONINFO os_vinfo;
memset(&os_vinfo, 0, sizeof(os_vinfo));
os_vinfo.dwOSVersionInfoSize = sizeof(os_vinfo);
GetVersionEx(&os_vinfo);
if( 6 <= os_vinfo.dwMajorVersion ) {
hDwmAPI_DLL = LoadLibrary("dwmapi.dll");
if( hDwmAPI_DLL ) {
*(PROC*)(&impl_DwmEnableBlurBehindWindow) =
GetProcAddress(hDwmAPI_DLL, "DwmEnableBlurBehindWindow");
*(PROC*)(&impl_DwmExtendFrameIntoClientArea) =
GetProcAddress(hDwmAPI_DLL, "DwmExtendFrameIntoClientArea");
*(PROC*)(&impl_DwmGetColorizationColor) =
GetProcAddress(hDwmAPI_DLL, "DwmGetColorizationColor");
}
}
HWND hWndGL = OpenGLWindowCreate(
"Test", "TestWnd",
ViewProc,
hInstance,
#if 1
WS_OVERLAPPEDWINDOW
#else
WS_POPUP
#endif
, WS_EX_APPWINDOW,
NULL);
if(!hWndGL) {
return -1;
}
UpdateWindow(hWndGL);
ShowWindow(hWndGL, SW_SHOW);
while( (bRet = GetMessage(&msg, NULL, 0, 0)) ) {
if(bRet == -1) {
// Handle Error
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
You can’t perform that action at this time.