【发布时间】:2019-11-06 13:16:05
【问题描述】:
更新:
问题解决了!该解决方案的灵感来自 cmets 中的建议:
我刚刚更新了图形驱动程序,现在我的所有代码都可以正常工作。 有关信息,提到的驱动程序是“Inter(R) UHD Graphics 620”,我已更新到版本 25.20.10.6472 (10/12/2018)。
非常抱歉给您带来不便,并感谢您的支持。
使用 ScreenToGif(感谢 Strive Sun)如下所示:主 (OpenGL) 窗口是某种太空船的外部视图(带有彩色助推器),右下角的(GDI)窗口是 AI Pilote 的视图,它正在学习吃绿色口香糖并避免吃红色口香糖)。
如果您,StackOverflow 先生,认为这种胡言乱语不合适,请删除它...
下面是原问题:
我在 windows 下有一小段 OpenGL 代码示例,可以在 windows 7 + visual studio 2010 中正常工作。 但是在我的装有 windows 10 + visual studio 2017 的新 PC 上,没有显示 OpenGL 渲染窗口。 编译没问题,执行过程中没有返回错误。
因此,为了在此处发布它而不用大量内容打扰您,我编写了我的代码的简短摘录。 它仅使用标准 win API (gl.h/glu.h) 提供的基本原生 gdi+opengl 函数,而不使用任何附加库(如 glew/glut/freeglut/...)。
使用 Windows7+VS2010 我有 3 个窗口:一个 GDI 渲染、一个 OpenGL 渲染和一个控制台。
- 第一个:一些交叉的蓝线(使用“LineTo”)。
- 第二个:一个紫色三角形(使用“glVertex3d”)。
- 在控制台上显示一条消息,告诉我所有函数都已正常返回。
在 Windows10+VS2017 中,OpenGL 窗口不可见。 当我使用 alt-tab 键玩游戏时,我什至看不到幽灵。
我认为 API 发生了一些变化,但我不知道是什么...
这是我的代码:
#include <windows.h>
#include <cstdio>
#include <GL/GLU.h>
static LRESULT CALLBACK win32callback ( HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam )
{
return DefWindowProcA( hWnd,message,wParam,lParam ) ;
}
HWND create_window ( BOOL & ok , int x )
{
WNDCLASSEXA wcx ;
memset( &wcx,0,sizeof( wcx )) ;
wcx.cbSize = sizeof( wcx ) ;
wcx.lpfnWndProc = win32callback ;
wcx.lpszClassName = "spam" ;
RegisterClassExA( &wcx ) ;
HWND hwnd = CreateWindowExA( 0,"spam",NULL,WS_POPUP,x+10,10,500,500,NULL,NULL,NULL,NULL ) ;
ok = ok && SetWindowPos( hwnd,HWND_TOPMOST,x+10,10,500,500,SWP_NOOWNERZORDER|SWP_SHOWWINDOW ) ;
ok = ok && ShowWindow( hwnd,SW_SHOWNORMAL ) ;
return hwnd ;
}
void play_opengl ( HWND hwnd , BOOL & ok )
{
HDC dc = GetWindowDC( hwnd ) ;
PIXELFORMATDESCRIPTOR pfd ;
memset( &pfd,0,sizeof( PIXELFORMATDESCRIPTOR )) ;
pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR ) ;
pfd.nVersion = 1 ;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER ;
pfd.iPixelType = PFD_TYPE_RGBA ;
pfd.cColorBits = 24 ;
pfd.cDepthBits = 32 ;
pfd.iLayerType = PFD_MAIN_PLANE ;
int PixFormat = ChoosePixelFormat( dc,&pfd ) ;
ok = ok && SetPixelFormat( dc,PixFormat,&pfd ) ;
HGLRC glrc = wglCreateContext( dc ) ;
ok = ok && wglMakeCurrent( dc,glrc ) ;
glViewport( 0,0,500,500 ) ;
glEnable( GL_COLOR_MATERIAL ) ;
glMatrixMode( GL_PROJECTION ) ;
gluPerspective( 70,1,0.1,1000 ) ;
glMatrixMode( GL_MODELVIEW ) ;
glLoadIdentity() ;
glColor3b( 100,50,120 ) ;
glTranslated( 0,0,-20 ) ;
glBegin( GL_TRIANGLES ) ;
glVertex3d( 0,0,0 ) ;
glVertex3d( 5,5,0 ) ;
glVertex3d( 0,5,0 ) ;
glEnd() ;
ok = ok && SwapBuffers( dc ) ;
}
void play_gdi ( HWND hwnd , BOOL & ok )
{
HDC windc = GetWindowDC( hwnd ) ;
HDC dc = CreateCompatibleDC( windc ) ;
HBITMAP bitmap = CreateCompatibleBitmap( windc,500,500 ) ;
HPEN pen = CreatePen( PS_SOLID,1,0xffaa55 ) ;
ok = ok && (SelectObject( dc,bitmap ) != NULL) ;
ok = ok && (SelectObject( dc,pen ) != NULL) ;
for ( int i = 0 ; i < 100 ; i++ )
ok = ok && LineTo( dc,(i&1?i:100-i)*4,(i&1)*400 ) ;
BitBlt( windc,0,0,500,500,dc,0,0,SRCCOPY ) ;
}
void main ()
{
BOOL ok = TRUE ;
HWND hwnd1 = create_window( ok,0 ) ;
HWND hwnd2 = create_window( ok,600 ) ;
play_gdi( hwnd1,ok ) ;
play_opengl( hwnd2,ok ) ;
// sorry I don't clean up anything...
if (ok) printf("\n all correct!\n") ;
printf("\n\n press ENTER") ;
getchar() ;
}
【问题讨论】:
-
如何添加一些错误处理以查看您进行的任何调用是否失败?如果他们这样做了,请告诉我们如何/有什么错误。现在,您的代码只是忽略了所有(潜在的)错误,并且无论如何都会伪造。还可以尝试在调试器中逐步运行它,并验证(返回和其他)值和控制流是否符合您的期望 - 如果不符合您的期望,请告诉我们它是如何/在哪里偏离的。
-
1.您缺少消息循环,2. void main() 错误,3. ShowWindow(hwnd,TRUE) 也错误,4. DefWindowProc 使用 RegisterClassExA 时错误,4. 这是不是最小。所有这些 OpenGL 调用都是多余的。
-
谢谢你们俩:我更新了我的代码以显示 GDI 和 OpenGL(只是为了检查窗口创建),测试所有函数返回(我在调试时已经这样做了),更正了一些参数并简化我的 OpenGL 调用。不幸的是它没有改变任何东西......
-
您仍然缺少message loop,这是必需的。来自文档:
If the thread creates one or more windows, a message loop must be provided。另请阅读 this 关于 void main() 的使用。 -
感谢@Axalo,我用正确的main签名编辑了我的代码并添加了一个message loop,但结果总是一样的。 .. 我认为这是一个更基本/更烦人的问题,因为我发现它在具有相同 Win10+VS2017 的另一台 PC 上运行良好!也许是一些图形驱动程序问题......这完全改变了这篇文章的意义。也许我应该重写问题或将其发布为新问题...
标签: c++ winapi opengl visual-studio-2017