什么是英特尔HD 3000上正确的OpenGL初始化?

时间:2013-09-30 16:26:29

标签: c++ windows opengl intel

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

经典的单一上下文 OpenGL 应用程序运行良好,但在单个应用程序中的多个 OpenGL 上下文中会产生奇怪的行为:

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

    现在我能够创建第二个渲染上下文但在释放之后(在使用/关闭窗口之后),驱动程序无法创建任何下一个渲染上下文。这已经在多个应用程序上进行了测试,并且始终表现相同。我希望通过让第二个上下文始终处于活动状态来克服这个问题,但它也不起作用(某种程度上,渲染上下文在英特尔上无效)。为清楚起见,第二个 OpenGL 渲染上下文用于打开/保存对话框(预览子窗口)。

  3. 驱动程序信息:

    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,...... 并经过多年测试。奇怪的行为仅出现在英特尔上。来自 nVidia 的卡工作正常并且 ATI / AMD 工作得很好(有一些问题,但它们与 ATI 的驱动程序相关,尤其是 VBO 与索引其他一切正常)

    2. 有没有更好的方法来启动/退出OpenGL?

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

      我现在正在使用wglMakeCurrent(hdc,hrc),但可能是我遗漏了某些内容,或者英特尔为此做了一些解决方法。

1 个答案:

答案 0 :(得分:0)

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

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

我喜欢使用SFML来创建OpenGL上下文和窗口,加上GLEW(仅对Windows来说是必需的)来设置OpenGL核心上下文函数。我也用glfw取得了成功,这对于加载OpenGL 3.2 +

非常有用