我试图用openGL创建自己的窗口。
到目前为止,一切都在被吸引。
我遇到的问题是,当我调整窗口大小时,一切都会消失。
如果我不使用DwmEnableBlurBehindWindow
,窗口会被拉黑,当调整大小时(我不想要这个)
#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <dwmapi.h>
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "dwmapi.lib")
const TCHAR szAppName[] = L"TransparentGL";
const TCHAR wcWndName[] = L"TransparentGL";
HDC hDC;
HGLRC m_hrc;
int w = 240;
int h = 240;
BOOL initSC()
{
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
return 0;
}
void resizeSC(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
BOOL renderSC()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
POINT start = { 2,2 };
POINT finish = { w - 2, h - 2 };
glColor3ub(0, 255, 0);
glBegin(GL_QUADS);
glVertex3i(-1, -1, -1);
glVertex3i(1, -1, -1);
glVertex3i(1, 1, -1);
glVertex3i(-1, 1, -1);
glEnd();
gluOrtho2D(0, w, 0, h);
glColor3ub(255, 255, 255);
glBegin(GL_QUADS);
glVertex2f(start.x, start.y);
glVertex2f(finish.x, start.y);
glVertex2f(finish.x, finish.y);
glVertex2f(start.x, finish.y);
glEnd();
glPopMatrix();
glFlush();
return 0;
}
BOOL CreateHGLRC(HWND hWnd)
{
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_SUPPORT_COMPOSITION | // Format Must Support Composition
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
32, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
8, // An Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
24, // 16Bit Z-Buffer (Depth Buffer)
8, // Some Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
HDC hdc = GetDC(hWnd);
int PixelFormat = ChoosePixelFormat(hdc, &pfd);
if (PixelFormat == 0) {
return FALSE;
}
BOOL bResult = SetPixelFormat(hdc, PixelFormat, &pfd);
if (bResult == FALSE) {
return FALSE;
}
m_hrc = wglCreateContext(hdc);
if (!m_hrc) {
return FALSE;
}
ReleaseDC(hWnd, hdc);
return TRUE;
}
LRESULT CALLBACK WindowFunc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
DWM_BLURBEHIND bb = { 0 };
HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
bb.hRgnBlur = hRgn;
bb.fEnable = TRUE;
DwmEnableBlurBehindWindow(hWnd, &bb);
CreateHGLRC(hWnd);
break;
}
case WM_DESTROY:
if (m_hrc) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hrc);
}
PostQuitMessage(0);
break;
case WM_SIZE:
{
w = LOWORD(lParam);
h = HIWORD(lParam);
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
resizeSC(w, h);
ReleaseDC(hWnd, hdc);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
{
wglMakeCurrent(hdc, m_hrc);
renderSC();
SwapBuffers(hdc);
}
EndPaint(hWnd, &ps);
break;
}
case WM_NCCALCSIZE:
return 0;
case WM_NCHITTEST:
{
LRESULT lResult = DefWindowProc(hWnd, msg, wParam, lParam);
if (lResult == HTCLIENT)
{
POINT pt = { LOWORD(lParam), HIWORD(lParam) };
ScreenToClient(hWnd, &pt);
if (GetActiveWindow() == hWnd)
{
if (pt.y < 31)
return HTCAPTION;
}
if (pt.y > (h - 10))
{
if (pt.x > (w - 10))
{
return HTBOTTOMRIGHT;
}
}
}
return lResult;
}
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str, int nWinMode)
{
WNDCLASSEX wc;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowFunc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hThisInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(0x00000000);
wc.lpszClassName = szAppName;
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, L"RegisterClassEx - failed", L"Error", MB_OK | MB_ICONERROR);
return FALSE;
}
HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW, szAppName, wcWndName,
WS_VISIBLE, 200, 150, w, h,
NULL, NULL, hThisInst, NULL);
if (!hWnd) {
MessageBox(NULL, L"CreateWindowEx - failed", L"Error", MB_OK | MB_ICONERROR);
return FALSE;
}
MSG msg;
while (GetMessageW(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (FALSE);
}
答案 0 :(得分:1)
将CS_OWNDC
,hbrBackground
添加到NULL
并覆盖WM_ERASEBKGND
。
答案 1 :(得分:0)
我遇到的问题是,当我调整窗口大小时,一切都会消失。
重绘WM_SIZE并禁用背景清除(不禁用背景清除的东西会闪烁)。您可以通过在WNDCLASS中设置NULL背景画笔并返回非零以响应WM_ERASEBKGD消息来完成此操作。
答案 2 :(得分:0)
在整个应用程序生命周期中,一劳永逸地保持窗口DC
。每当您使用CS_OWNDC
或GetDC
获得DC时,如果您没有在课堂风格中使用BeginPaint
或其他DC保留标记,那么您将获得字面上的新DC,即不再与GL上下文相关联。
所以,这就是你应该拥有的:
// app init
HWND mywnd = CreateMyWindow();
HDC mywnddc = GetDC(mywnd);
// create context for mywnddc and make it current on mywnddc!
// paint
BeginPaint(wnd, &ps);
EndPaint(&ps);
SwapBuffers(mywnddc); // not the DC you get by BeginPaint!
// app finish
ReleaseDC(mywnd, mywnddc);
如果您不在多个窗口上使用渲染,那么每次想要绘制时都无法调用wglMakeCurrent
,只能调用一次。