Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 975
Spektre Avatar asked Sep 30 '13 16:09

Spektre


Video Answer


1 Answers

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+

like image 108
Matt Fichman Avatar answered Sep 22 '22 13:09

Matt Fichman