¿Cuál es la inicialización correcta de OpenGL en Intel HD 3000?

Tengo un problema con los gráficos Intel HD 3000 en el portátil Toshiba (OS Win7 x32, lang C ++) .

Las aplicaciones de OpenGL de contexto único clásico funcionan bien, pero en múltiples contextos de OpenGL en aplicaciones individuales crea un comportamiento extraño:

  1. en versiones anteriores de mis aplicaciones, el controlador de Intel no puede crear un segundo contexto de renderizado.
  2. después de cambios importantes en mi comportamiento de architecture de software basado en OpenGL cambiado

    ahora puedo crear un segundo contexto de representación, pero después de soltarlo (después de usar / cerrar ventana) el controlador no puede crear ningún contexto de representación siguiente. Esto se ha probado en más de una aplicación y se comporta igual todo el tiempo. Quería superar esto teniendo activado el segundo contexto en todo momento, pero tampoco funciona (de alguna manera, el contexto de representación se invalida en Intel). Para mayor claridad, el segundo contexto de representación de OpenGL se utiliza para los cuadros de diálogo Abrir / Guardar ( subventanas de vista previa).

Información del conductor:

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

Inicio y salida del código OpenGL (desde mi motor 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; } //------------------------------------------------------------------------------ 

ahora las preguntas:

  1. ¿Estoy haciendo algo mal?

    El motor es completamente funcional GL, GLSL, VBO, VAO, … y probado durante años. El comportamiento raro solo está presente en Intel . Las tarjetas de nVidia funcionan bien y ATI / AMD funciona casi de maravilla (hay algunos problemas, pero están relacionados con controladores de errores como siempre para ATI especialmente para VBO con índices, todo lo demás funciona bien)

  2. ¿Hay una mejor manera de iniciar / salir de OpenGL?

  3. ¿Cómo cambiar correctamente entre diferentes contextos de representación?

    Estoy usando wglMakeCurrent(hdc,hrc) por ahora, pero puede ser que me falta algo o hay alguna solución en Intel para esto.

Su uso de WGL me parece correcto (incluido el uso de wglMakeCurrent), pero no lo he usado por un tiempo, por lo que mi memoria puede estar nublada (para responder Q1 y Q3).

Sin embargo, hay una mejor manera de inicializar OpenGL: use una biblioteca de carga, como se detalla aquí . Como dice el wiki, es muy recomendable utilizar una biblioteca de carga en lugar de intentar hacerlo usted mismo.

Me gusta usar SFML para crear el contexto y la ventana de OpenGL, además de GLEW (solo necesario para Windows) para configurar las funciones de contexto del núcleo de OpenGL. También he tenido éxito con glfw, que es bueno para cargar OpenGL 3.2+