【问题标题】:What is the proper OpenGL initialisation on Intel HD 3000?Intel HD 3000 上正确的 OpenGL 初始化是什么?
【发布时间】:2013-10-06 14:35:34
【问题描述】:

我在Toshiba笔记本(OS Win7 x32, lang C++)上遇到Intel graphics HD 3000问题。

经典的单一上下文 OpenGL 应用程序可以正常工作,但在单个应用程序中的多个 OpenGL 上下文中会产生奇怪的行为:

  1. 在我的应用程序的旧版本上,英特尔驱动程序根本无法创建第二个渲染上下文。

  2. 在我的基于 OpenGL 的软件架构行为发生重大变化后

    现在我可以创建第二个渲染上下文,但在释放它之后(使用/关闭窗口后)驱动程序无法创建任何下一个渲染上下文。这已经在多个应用程序上进行了测试,并且始终表现相同。我想通过让第二个上下文始终处于活动状态来克服这个问题,但它也不起作用(不知何故,渲染上下文在英特尔上无效)。为清楚起见,第二个 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. 我做错了吗?

    引擎功能齐全GL、GLSL、VBO、VAO、...并经过多年测试。奇怪的行为只存在于 Intel 上。 nVidia 的显卡运行良好,ATI/AMD 运行良好(存在一些问题,但它们与 ATI 的驱动程序始终相关,特别是对于VBO 带索引一切正常)

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

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

    我现在正在使用wglMakeCurrent(hdc,hrc),但可能是我遗漏了什么,或者英特尔有一些解决方法。

【问题讨论】:

  • 您是否习惯使用 WGL?

标签: c++ windows opengl intel


【解决方案1】:

您对 WGL 的使用在我看来是正确的(包括您对 wglMakeCurrent 的使用),但我有一段时间没有使用它了,所以我的记忆可能模糊不清(回答 Q1 和 Q3)。

但是,一种更好的初始化 OpenGL 的方法:使用加载程序库,as detailed here。正如 wiki 所说,强烈建议使用加载程序库而不是尝试自己做。

我喜欢使用SFML 来创建OpenGL 上下文和窗口,加上GLEW(仅Windows 需要)来设置OpenGL 核心上下文函数。我在 glfw 上也取得了成功,它非常适合加载 OpenGL 3.2+

【讨论】:

  • 我已经将 GLEW 和 OpenGL 4.2 用于 decend gfx 卡,但对于 Intel,由于驱动程序错误,它无法使用。我不喜欢在不知道它是否真的有帮助(我的问题看起来像驱动程序内部的错误)以及许多其他原因(如连续性、兼容性等)的情况下添加另一个第 3 方库的想法长期运行
  • 卡/驱动程序配置只允许 OpenGL 3.1.0 上下文,没有库可以帮助只有像 nvemulate 这样的仿真器......或者更好的驱动程序存在和不存在(至少不是来自英特尔)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
相关资源
最近更新 更多