Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
165 views
in Technique[技术] by (71.8m points)

c++ - What is the proper OpenGL initialisation on Intel HD 3000?

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:

  1. on older versions of my apps the Intel driver cannot create second rendering context at all.

  2. 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:

  1. 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)

  2. Is there a better way to init/exit OpenGL?

  3. 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).

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.

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+


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...