Intel HD 3000上正确的OpenGL初始化是什么?

东芝笔记本上的英特尔graphicsHD 3000有问题(OS Win7 x32,lang C ++)

古典的单一上下文OpenGL应用程序工作正常,但在单个应用程序中的多个OpenGL上下文创build奇怪的行为:

  1. 在较早版本的应用程序中,英特尔驱动程序根本无法创build第二个渲染上下文。
  2. 我的基于OpenGL的软件体系结构行为发生了重大变化

    现在我可以创build第二个渲染上下文,但是在释放之后(在使用/closures窗口之后),驱动程序不能创build任何下一个渲染上下文。 这已经在多个应用程序上进行过testing,并且始终保持相同的状态。 我希望通过让第二个上下文始终处于活动状态来解决这个问题,但是它也不能工作(某种程度上,渲染上下文在Intel上是无效的)。 为了清晰起见,第二个OpenGL渲染上下文用于打开/保存对话框 (预览子窗口)。

司机信息:

Intel(R) HD Graphics 3000 OpenGL ver: 3.1.0 - Build 9.17.10.2932 

初始化并退出OpenGL代码 (从我的OpenGL引擎):

 //------------------------------------------------------------------------------ int OpenGLscreen::init(void *f,int textures) { if (_init) exit(); frm=(formtype*)f; hdc = GetDC(frm->Handle); // get device context int i; if (!_used) { int i,_pfid=-1,_zbit=0; PIXELFORMATDESCRIPTOR _pfd; #define pfd_test i=ChoosePixelFormat(hdc,&pfd); DescribePixelFormat(hdc,i,sizeof(_pfd),&_pfd); if (_zbit<_pfd.cDepthBits) { _zbit=_pfd.cDepthBits; _pfid=i; } pfd.cColorBits = 32; pfd.cDepthBits = 32; pfd_test; pfd.cColorBits = 24; pfd.cDepthBits = 32; pfd_test; pfd.cColorBits = 16; pfd.cDepthBits = 32; pfd_test; pfd.cColorBits = 32; pfd.cDepthBits = 24; pfd_test; pfd.cColorBits = 24; pfd.cDepthBits = 24; pfd_test; pfd.cColorBits = 16; pfd.cDepthBits = 24; pfd_test; pfd.cColorBits = 32; pfd.cDepthBits = 16; pfd_test; pfd.cColorBits = 24; pfd.cDepthBits = 16; pfd_test; pfd.cColorBits = 16; pfd.cDepthBits = 16; pfd_test; #undef pfd_test pfd.cDepthBits = _zbit; // iba koli warningu DescribePixelFormat(hdc,_pfid,sizeof(pfd),&pfd); pfid=ChoosePixelFormat(hdc,&pfd); SetPixelFormat(hdc,pfid,&pfd); DescribePixelFormat(hdc,pfid,sizeof(pfd),&pfd); znum=1<<(pfd.cDepthBits-1); } // create current rendering context hrc = wglCreateContext(hdc); if(hrc == NULL) { ShowMessage("Could not initialize OpenGL Rendering context !!!"); _init=0; return 0; } if(wglMakeCurrent(hdc, hrc) == false) { ShowMessage("Could not make current OpenGL Rendering context !!!"); wglDeleteContext(hrc); // destroy rendering context _init=0; return 0; } if (!_used) glewInit(); _init=1; _used=1; resize(0,0,128,128); // glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // glFrontFace(GL_CCW); // predna strana je proti smeru hod. ruciciek // glEnable(GL_CULL_FACE); // vynechavaj odvratene steny // glEnable(GL_TEXTURE_2D); // pouzivaj textury, farbu pouzivaj z textury // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); // glEnable(GL_BLEND); // priehladnost // glBlendFunc(GL_SRC_ALPHA,GL_DST_ALPHA); /* glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); GLdouble MaterialAmbient [] = {0.25, 0.25, 0.25, 1.00}; GLdouble MaterialDiffuse [] = {0.25, 0.25, 0.25, 1.00}; GLdouble MaterialSpecular [] = {0.50, 0.50, 0.50, 1.00}; GLdouble MaterialShininess[] = {15.0}; // 0-ufocused, 128 max focus glMaterialfv(GL_FRONT, GL_AMBIENT , MaterialAmbient ); glMaterialfv(GL_FRONT, GL_DIFFUSE , MaterialDiffuse ); glMaterialfv(GL_FRONT, GL_SPECULAR , MaterialSpecular ); glMaterialfv(GL_FRONT, GL_SHININESS, MaterialShininess); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); GLdouble LightPosition [] = {0.00, 0.00, 0.00, 0.0}; GLdouble LightAmbient [] = {0.10, 0.10, 0.10, 1.0}; GLdouble LightDiffuse [] = {0.20, 0.20, 0.20, 1.0}; GLdouble LightSpecular [] = {1.00, 1.00, 1.00, 1.0}; glLightfv(GL_LIGHT0,GL_AMBIENT ,LightAmbient ); glLightfv(GL_LIGHT0,GL_DIFFUSE ,LightDiffuse ); glLightfv(GL_LIGHT0,GL_SPECULAR,LightSpecular); glLightfv(GL_LIGHT0,GL_POSITION,LightPosition); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, LightAmbient); */ glEnable(GL_DEPTH_TEST); // Zbuf glShadeModel(GL_SMOOTH); // gourard shading glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // background color glDepthFunc(GL_LEQUAL); const GLubyte *p; char a; // get extensions list extensions=""; #define ext_add if ((extensions!="")&&(extensions[extensions.Length()]!=' ')) extensions+=' '; for (i=0;;i++) { a=p[i]; if (!a) break; extensions+=a; } p=glGetString(GL_EXTENSIONS); ext_add; if (wglGetExtensionsStringARB) p=wglGetExtensionsStringARB(hdc); ext_add; if (wglGetExtensionsStringEXT) p=wglGetExtensionsStringEXT(); ext_add; // int hnd=FileCreate("glext.txt"); FileWrite(hnd,scr.extensions.c_str(),scr.extensions.Length()); FileClose(hnd); OpenGLtexture txr; txrs.alloc(textures); // allocate textures name space font_init(txr); font=txrs.add(txr); s3dl=txrs.add(txr); txrs.sizes[s3dl]._mode=GL_MODULATE; s3dr=txrs.add(txr); txrs.sizes[s3dr]._mode=GL_MODULATE; return 1; } //------------------------------------------------------------------------------ void OpenGLscreen::exit() { if (!_init) return; wglMakeCurrent(hdc,hrc); // use this context if multiple OpenGLs are used txrs.free(); wglMakeCurrent(NULL, NULL); // release current rendering context wglDeleteContext(hrc); // destroy rendering context hrc=NULL; _init=0; } //------------------------------------------------------------------------------ 

现在的问题:

  1. 难道我做错了什么?

    引擎是完全functionGL,GLSL,VBO,VAO,…并testing多年。 奇怪的行为只出现在英特尔 。 从nVidia的卡工作正常, ATI / AMD工作几乎没有问题(有一些问题,但他们是像往常一样的ATI,特别是对于VBO的索引,一切正常)

  2. 有没有更好的方法来初始化/退出OpenGL?

  3. 如何正确地切换不同的渲染上下文?

    我现在正在使用wglMakeCurrent(hdc,hrc) ,但可能是我缺less一些东西,或者有一些解决scheme在英特尔这个。

你对WGL的使用对我来说是正确的(包括你对wglMakeCurrent的使用),但是我一段时间都没有用过,所以我的记忆可能会模糊(回答Q1和Q3)。

但是,有一个更好的方法来初始化OpenGL:使用一个加载器库, 详细在这里 。 正如维基所说,强烈建议使用一个加载程序库,而不是试图自己做。

我喜欢使用SFML创建OpenGL上下文和窗口,再加上GLEW (仅在Windows中需要)来设置OpenGL核心上下文功能。 我也有成功与glfw,这是很好的加载OpenGL 3.2 +