I have a problem with Intel graphics HD 3000 on Toshiba notebook (OS Win7 x32, lang C++).
Classical single context OpenGL applications work fine but on multiple OpenGL contexts in single App creates weird behavior:
on older versions of my apps the Intel driver cannot create second rendering context at all.
after major changes in my OpenGL based software architecture behavior changed
now I am able to create second rendering context but after releasing it (after use / close window) the driver cannot create any next rendering context. This has been tested on more than one app and behaves the same all the time. I wanted to get over this by having the second context at all time active but it does not work too (somehow rendering context is invalidated on Intel). For clarity the second OpenGL rendering context is used for Open/Save dialogs (preview sub-windows).
Driver info:
Intel(R) HD Graphics 3000
OpenGL ver: 3.1.0 - Build 9.17.10.2932
Init and exit OpenGL code (from my OpenGL engine):
//------------------------------------------------------------------------------
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;
}
//------------------------------------------------------------------------------
now the questions:
Am I doing something wrong?
Engine is fully functional GL,GLSL,VBO,VAO,... and tested for years. Weird behavior is present only on Intel. Cards from nVidia works fine and ATI/AMD works almost fine (there are some issues but they are buggy drivers related as always for ATI especially for VBO with indices everything else works fine)
Is there a better way to init/exit OpenGL?
How to properly switch between different rendering contexts?
I am using wglMakeCurrent(hdc,hrc)
for now but may be I am missing something or there is some workaround on Intel for this.
Question&Answers:
os