Intel HD 3000 上正确的 OpenGL 初始化是什么?
我在 Toshiba 笔记本(OS Win7 x32,lang C++)上使用 Intel graphics HD 3000 有问题.
I have a problem with Intel graphics HD 3000 on Toshiba notebook (OS Win7 x32, lang C++).
经典的单上下文 OpenGL 应用程序工作正常,但在单个应用程序中的多个 OpenGL 上下文上会产生奇怪的行为:
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.
在我的基于 OpenGL 的软件架构行为发生重大变化后
after major changes in my OpenGL based software architecture behavior changed
现在我可以创建第二个渲染上下文,但是在释放它之后(使用/关闭窗口后),驱动程序无法创建任何下一个渲染上下文.这已经在多个应用程序上进行了测试,并且一直表现相同.我想通过让第二个上下文始终处于活动状态来解决这个问题,但它也不起作用(不知何故渲染上下文在英特尔上无效).为清楚起见,第二个 OpenGL 渲染上下文用于打开/保存对话框(预览子窗口).
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).
司机信息:
Intel(R) HD Graphics 3000
OpenGL ver: 3.1.0 - Build 9.17.10.2932
初始化和退出 OpenGL 代码(来自我的 OpenGL 引擎):
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;
}
//------------------------------------------------------------------------------
现在是问题:
我做错了什么吗?
引擎功能齐全GL、GLSL、VBO、VAO... 并经过多年测试.奇怪的行为仅在 Intel 上出现.nVidia 的显卡可以正常工作,ATI/AMD 几乎可以正常工作(存在一些问题,但它们是与 ATI 始终相关的错误驱动程序,尤其是对于VBO 与索引其他一切正常)
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)
是否有更好的方法来初始化/退出 OpenGL?
如何在不同的渲染上下文之间正确切换?
我现在正在使用 wglMakeCurrent(hdc,hrc)
,但可能是我遗漏了什么,或者英特尔有一些解决方法.
I am using wglMakeCurrent(hdc,hrc)
for now but may be I am missing something or there is some workaround on Intel for this.
推荐答案
你对 WGL 的使用在我看来是正确的(包括你对 wglMakeCurrent 的使用),但我有一段时间没有使用它,所以我的记忆可能有模糊(回答 Q1 和 Q3).
Your use of WGL looks correct to me (including your use of wglMakeCurrent), but I haven't used it in a while, so my memory might be foggy (to answer Q1 and Q3).
但是,有一种更好的初始化 OpenGL 的方法:使用加载程序库,详见此处.正如维基所说,强烈建议使用加载程序库,而不是尝试自己做.
However, there is a better way to initialize OpenGL: use a loader library, as detailed here. As the wiki says, it's highly recommended to use a loader library rather than attempting to do it yourself.
我喜欢使用 SFML 来创建 OpenGL 上下文和窗口,加上 GLEW(仅适用于 Windows)来设置 OpenGL 核心上下文函数.我也成功使用 glfw,这对加载 OpenGL 3.2+ 很有用
I like to use SFML to create the OpenGL context and window, plus GLEW (only necessary for Windows) to set up the OpenGL core context functions. I've also had success with glfw, which is good for loading OpenGL 3.2+
相关文章