OpenGL在子窗口中运行时隐藏表面去除的问题
我目前正在尝试用openGL绘制二次曲面。当使用单个窗口时,我的程序可以很好地运行。现在我需要一个控制面板,所以我创建了两个窗口,一个是框架窗口,另一个是子窗口OpenGL运行。但是当openGL在子窗口中运行时,隐藏表面去除是有问题的,而如果我使用单个窗口,则不存在这个问题。我没有更改绘图函数,只是获取子窗口的dc并设置rc。这是代码。谢谢您的帮助。
#include <windows.h> //Windows header
#include <gl\glut.h> //glut
#include <gl\glaux.h> //glaux
#define hID 6310 //ID of child window
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK OpenProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR szChildClass[] = TEXT ("OpenGL"); //child window class name
TCHAR szAppName[] = TEXT ("Frame"); //frame window class name
HWND hwndopen; //child window
handle
HWND hwnd; //frame window handle
MSG msg ; //message structure
HDC hdc = NULL; //device context used in child window
HGLRC hrc = NULL; //rendering context
HINSTANCE hInstance; //application instance
GLuint PixelFormat; //pixformat
BOOL active=TRUE;
BOOL keys[256];
float rquad[3]={0,0,0}; //angle of rotate
// pfd Tells Windows How We Want Things To Be
static PIXELFORMATDESCRIPTOR pfd={
sizeof(PIXELFORMATDESCRIPTOR),
1,PFD_DRAW_TO_WINDOW|
PFD_SUPPORT_OPENGL|
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
16,
0, 0, 0, 0, 0, 0,
0,0,0,0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
/* Here I draw a color cube and I draw black line in every edge
of the cube,the I draw 3 color lines to show x,y,z coordinate
axis*/
int DrawGLScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-10.0f);
glRotatef(rquad[0],1.0f,0.0f,0.0f);
glRotatef(rquad[1],0.0f,1.0f,0.0f);
glRotatef(rquad[2],0.0f,0.0f,1.0f);
glBegin(GL_QUADS);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glColor3f(1.0f,0.5f,0.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glColor3f(1.0f,1.0f,0.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glColor3f(1.0f,0.0f,1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glEnd();
glBegin(GL_LINES);
glColor3f(1.0f,1.0f,1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f( -1.0f, 1.0f, 1.0f);
glVertex3f( -1.0f, -1.0f, 1.0f);
glVertex3f( -1.0f, 1.0f, -1.0f);
glVertex3f( -1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glEnd();
glBegin(GL_LINES);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 0.0f, 0.0f);
glVertex3f( 10.0f, 0.0f, 0.0f);
glColor3f(1.0f,1.0f,0.0f);
glVertex3f( 0.0f, 0.0f, 0.0f);
glVertex3f( 0.0f, 10.0f, 0.0f);
glColor3f(1.0f,0.0f,1.0f);
glVertex3f( 0.0f, 0.0f, 0.0f);
glVertex3f( 0.0f, 0.0f, 10.0f);
glEnd();
return TRUE;
}
BOOL InitGL(void) //init opengl
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(1.0f,0.0f,1.0f,0.5f);
glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return TRUE;
}
// resize the opengl scene in child window
void ReSizeGLScene(int width, int height)
{
if (height==0) //avoid zero to be the divisor
{
height=1;
}
glViewport(0,0,(int)width,(int)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(float)width/(float)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
WNDCLASS wndclass ;
BOOL flag=TRUE;
hInstance = GetModuleHandle(NULL);
InitGL();
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL,"窗口类注册失败","演示程序 ",MB_OK|MB_ICONINFORMATION);
return 0;
}
wndclass.lpfnWndProc = OpenProc ;
wndclass.cbWndExtra = sizeof (long) ;
wndclass.hIcon = NULL ;
wndclass.hbrBackground = NULL;
wndclass.lpszClassName = szChildClass ;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL,"子窗口类注册失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if(!(hwnd = CreateWindow (szAppName, TEXT ("Frisa"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL)))
{
MessageBox(NULL,"窗口创建失败","演示程序",MB_OK|MB_ICONINFORMATION);
return FALSE;
}
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (flag)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
if (!UnregisterClass(szChildClass,hInstance))
{
MessageBox(NULL,"子窗口类注销失败","演示程序",MB_OK | MB_ICONINFORMATION);
hInstance=NULL;
}
if (!UnregisterClass(szAppName,hInstance))
{
MessageBox(NULL,"窗口类注销失败","演示程序",MB_OK | MB_ICONINFORMATION);
hInstance=NULL;
}
flag=FALSE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
if (active && !DrawGLScene()) // Active? Was There A Quit Received?
{
flag=FALSE; // ESC or DrawGLScene Signalled A Quit
}
else // Not Time To Quit, Update Screen
{
SwapBuffers(hdc); // Swap Buffers (Double Buffering)
}
if(keys[VK_RIGHT]){rquad[0]+=0.12;}
if(keys[VK_LEFT]){rquad[0]=0;rquad[1]=0;rquad[2]=0;}
if(keys[VK_UP]){rquad[1]+=0.12;}
if(keys[VK_DOWN]){rquad[2]+=0.12;}
}
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int cxBlock, cyBlock;
switch (message)
{
case WM_CREATE :
if(!(hwndopen= CreateWindow (szChildClass, NULL,
WS_CHILDWINDOW | WS_VISIBLE,
0, 0, 0, 0,
hwnd,(HMENU)(hID),
(HINSTANCE)GetWindowLong (hwnd, GWL_HINSTANCE),
NULL)))
{
MessageBox(NULL,"子窗口创建失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if (!(hdc=GetDC(hwndopen)))
{
MessageBox(NULL,"设备描述表创建失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if (!(PixelFormat=ChoosePixelFormat(hdc,&pfd)))
{
MessageBox(NULL,"未找到匹配的像素格式","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if(!SetPixelFormat(hdc,PixelFormat,&pfd))
{
MessageBox(NULL,"设置像素格式失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if (!(hrc=wglCreateContext(hdc)))
{
MessageBox(NULL,"获取渲染描述表失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if(!wglMakeCurrent(hdc,hrc))
{
MessageBox(NULL,"渲染描述表激活失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
return 0 ;
case WM_ACTIVATE: // Watch For Window Activate Message
// LoWord Can Be WA_INACTIVE, WA_ACTIVE, WA_CLICKACTIVE,
// The High-Order Word Specifies The Minimized State Of The Window Being Activated Or Deactivated.
// A NonZero Value Indicates The Window Is Minimized.
if ((LOWORD(wParam) != WA_INACTIVE) && !((BOOL)HIWORD(wParam)))
active=TRUE; // Program Is Active
else
active=FALSE; // Program Is No Longer Active
return 0; // Return To The Message Loop
case WM_SIZE :
cxBlock = LOWORD (lParam);
cyBlock = HIWORD (lParam);
MoveWindow (hwndopen,
5,5,
(int)(cxBlock*0.80),(int)(cyBlock*0.98), TRUE) ;
ReSizeGLScene((int)(cxBlock*0.80),(int)(cyBlock*0.97));
return 0 ;
case WM_LBUTTONDOWN :
MessageBeep (0) ;
return 0 ;
case WM_KEYDOWN:
keys[wParam] = TRUE;
return 0;
case WM_KEYUP:
keys[wParam] = FALSE;
return 0;
case WM_CLOSE:
DestroyWindow(hwnd);
return 0;
case WM_DESTROY :
if (hrc)
{
if (!wglMakeCurrent(hdc,NULL))
{
MessageBox(NULL,"DC和RC关联解除失败","演示程序",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hrc))
{
MessageBox(NULL,"RC释放失败","演示程序",MB_OK | MB_ICONINFORMATION);
}
hrc=NULL;
}
if (!DestroyWindow(hwnd))
{
MessageBox(NULL,"窗口句柄释放失败","演示程序",MB_OK | MB_ICONINFORMATION);
hwnd=NULL;
}
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
LRESULT CALLBACK OpenProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
添加
我的目标是用OpenGL在子窗口中绘制一个颜色立方体。子窗口的大小约为框架窗口大小的0.8倍。我将在框架窗口的其余区域添加一个控制面板。我的程序可以绘制一个彩色立方体。但问题是我可以看到立方体的所有 6 个面和所有 12 个边。我不确定,但看起来隐藏表面删除失败。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我发现我犯了低级错误。OpenGL的初始化应该在创建子窗口之后进行,但我把它放在顶部,所以它不起作用。
I find I have a Low-level errors committed.The initialization of OpenGL should be after the creation of the child window,but I put it at top,so it does not work.
将 CS_OWNDC 添加到您的窗口类,否则嵌入窗口将与其父窗口共享其 DC。 OpenGL 窗口应该始终获得自己的 DC,因此对于 OpenGL 窗口类:
由于注释而编辑
我也没有看到实际设置的 PIXELFORMATDESCRIPTOR。您能否显示代码,其中您选择了一个最接近您的请求的 PFD(API 调用
ChoosePixelFormat
、DescribePixelFormat
)并将其设置在您的窗口上 (SetPixelFormat< /code> API 调用)。另外,为了进行调试,您应该转储系统根据您的请求返回的 PFD。
除此之外,使用 OpenGL 的窗口应使用窗口样式创建
WS_CLIPCHILDREN | WS_CLIPSIBLINGS
Add CS_OWNDC to your windowclass, otherwise a embedded window will share its DC with its parent. OpenGL windows should always get their own DC, so for OpenGL Window class:
EDIT due to comment
I also don't see the PIXELFORMATDESCRIPTOR being actually set. Could you please show the code where you select the one PFD most closely resembling your request (API calls
ChoosePixelFormat
,DescribePixelFormat
) and setting it on your window (SetPixelFormat
API call). Also for debugging you should dump the PFD the system returned upon your request.In addition to that, windows using OpenGL should be created with window styles
WS_CLIPCHILDREN | WS_CLIPSIBLINGS
我已经解决了这个问题,这是关于OpenGL初始化的位置。初始化必须在OpenGL运行的子窗口创建之后。在上面的代码中,我在winmain()函数的开头初始化OpenGL,但是子窗口当时窗口不存在。
I have solved the problem,it's about the location of the OpenGL initialization.The initializationmust be after the creation of the child window in which OpenGL runs.In the above code,I init OpenGL at the beginning of winmain() function ,but the child window does not exist at that time.