Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

1

27.01.2013, 20:07

Best way to create OpenGL render context

Hallo Forum

Ich benutze seit einiger Zeit GLEW und bin jetzt auf das Henne-Ei-Problem Renderkontext gestoßen.
Das Problem ist dass man glewInit() nur mit einem gültigen Renderkontext aufrufen kann, auf der anderen Seite aber
eine initialisierte GLEW LIB benötigt um wglChoosePixelFormatARB und wglCreateContextAttribsARB aufrufen zu können.
Im Internet taucht dazu immer der Lösungsansatz auf 'erstelle einen Dummy-Kontext', 'initialisiere damit GLEW', 'schmeiß den
Dummy-Kontext weg und erzeuge einen neuen mit wglChoosePixelFormatARB und wglCreateContextAttribsARB'.
Soweit so gut. Funktioniert auch. Nur wenn ich mein Programm mit gDEBugger teste kriege ich haufenweise die Meldung:

Zitat

Detected error: The debugged process asked for an extension function pointer (glUniformMatrix3fv) from one render context, but called this function pointer in another render context (context #2)

Das liegt vermutlich daran, dass GLEW seine Funktionspointer mit dem besagten Dummy-Kontext initialisiert hat.
Habe auch schon versucht glewInit() nochmal unter dem neuen Kontext aufzurufen. Bringt aber nichts.

Hier noch meine Initialisierungsfunktion ...

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
void GL::_EnableOpenGL(HWND hWnd)
{
    int nPixelFormat  = -1;
    PIXELFORMATDESCRIPTOR pfd;
    int format;

    // disable if enabled
    _DisableOpenGL();

    // init win handle
    GL::m_hWnd = hWnd;  

    // get dummy device context (DC)
    GL::m_hDC_Dummy = GetDC( GL::m_hWnd );
    
    // set dummy pixel format to get dummy render context to init glew
    ZeroMemory( &pfd, sizeof( pfd ) );
    pfd.nSize = sizeof( pfd );
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    format = ChoosePixelFormat( GL::m_hDC_Dummy, &pfd );
    SetPixelFormat( GL::m_hDC_Dummy, format, &pfd );
    
    // create and enable dummy render context (RC)
    GL::m_hRC_Dummy = wglCreateContext( GL::m_hDC_Dummy );
    wglMakeCurrent( GL::m_hDC_Dummy, GL::m_hRC_Dummy );

    // init glew
    GLenum glewInitRet = glewInit();
    if(glewInitRet != GLEW_OK)
    {
        _DisableOpenGL();
        std::string strMsg;
        strMsg = "Initialisation of GLEW failed !";
        throw strMsg;
    }
    
    // check if OpenGL 3.3 core is supported
    if(!GLEW_VERSION_3_3)
    {
        _DisableOpenGL();       
        std::string strMsg;
        strMsg = "OpenGL 3.3 core is not supported on this system !";
        throw strMsg;
    }

    // get device context (DC)
    GL::m_hDC = GetDC( GL::m_hWnd );

    // Specify the important attributes we care about
    int nPixCount = 0;
    int pixAttribs[] = { WGL_SUPPORT_OPENGL_ARB,    GL_TRUE,
                         WGL_DOUBLE_BUFFER_ARB,     GL_TRUE,
                         WGL_DRAW_TO_WINDOW_ARB,    GL_TRUE,
                         WGL_ACCELERATION_ARB,      WGL_FULL_ACCELERATION_ARB,
                         WGL_RED_BITS_ARB,          8,
                         WGL_GREEN_BITS_ARB,        8,
                         WGL_BLUE_BITS_ARB,         8,
                         WGL_ALPHA_BITS_ARB,        8,
                         WGL_DEPTH_BITS_ARB,        16,
                         WGL_PIXEL_TYPE_ARB,        WGL_TYPE_RGBA_ARB,
                         0}; // NULL termination

    // Ask OpenGL to find the most relevant format matching our attribs
    // Only get one format back.
    wglChoosePixelFormatARB(m_hDC, &pixAttribs[0], NULL, 1, &nPixelFormat, (UINT*)&nPixCount);
    if(nPixelFormat == -1) 
    {
        _DisableOpenGL();
        std::string strMsg;
        strMsg = "Finding a pixel format with the requested attributes failed !";
        throw strMsg;
    }

    // Got a format, now set it as the current one
    SetPixelFormat( m_hDC, nPixelFormat, &pfd );

    GLint attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB,  3,
                       WGL_CONTEXT_MINOR_VERSION_ARB,  3,
                       0 };
    m_hRC = wglCreateContextAttribsARB(m_hDC, 0, attribs);
    if (m_hRC == NULL)
    {
        _DisableOpenGL();
        std::string strMsg;
        strMsg = "Creating OpenGL 3.3 context failed !";
        throw strMsg;
    }

    // throw away the dummy stuff
    wglMakeCurrent( NULL, NULL );
    wglDeleteContext( GL::m_hRC_Dummy );
    GL::m_hRC_Dummy = NULL;
    ReleaseDC( GL::m_hWnd, GL::m_hDC_Dummy );
    GL::m_hDC_Dummy = NULL;

    BOOL bRet = wglMakeCurrent( m_hDC, m_hRC );
    if(bRet == FALSE)
    {
        _DisableOpenGL();
        std::string strMsg;
        strMsg = "Setting OpenGL context as current failed ! !";
        throw strMsg;
    }

    // read OpenGL data
    GL::m_strVendor   = (char*)glGetString(GL_VENDOR);
    GL::m_strRenderer = (char*)glGetString(GL_RENDERER);
    GL::m_strOpenGLVersion  = (char*)glGetString(GL_VERSION);
}


Hat jemand eine Idee wie man einen Kontext ohne diesen Dummysch... erzeugen kann und gleichzeitig GLEW befriedigt ?
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

27.01.2013, 21:15

Man macht es wirklich mit einem Kontext, auch außerhalb von GLEW. Man holt sich einen normalen Context und bekommt dort Zugriff auf die Extensions mit denen man einen neuen Context anfordern kann. Das ist so weit ich weiß auch explizit so vom ARB im OpenGL Standard spezifiziert.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

3

27.01.2013, 21:45

Man macht es wirklich mit einem Kontext, auch außerhalb von GLEW. Man holt sich einen normalen Context und bekommt dort Zugriff auf die Extensions mit denen man einen neuen Context anfordern kann. Das ist so weit ich weiß auch explizit so vom ARB im OpenGL Standard spezifiziert.

Hatte ich ja auch schon so recherchiert und auch entsprechend umgesetzt.
Verwirrt hat mich dann nur die Warnung von gDEBugger weil diese auf etwas hinweist was eigentlich unausweichlich ist. ?(
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

27.01.2013, 23:18

Die Warnung ist korrekt, das ist streng genommen falsch. Initialisier GLEW erst, nachdem du deinen richtigen Kontext erzeugt hast.

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

5

28.01.2013, 05:50

Manchmal kann man gar nicht so viel essen wie man kotzen möchte !!! :cursing: :cursing: :cursing: :cursing: :cursing: :cursing:

Hab glewInit() jetzt erst mit meinem finalen Kontext aufgerufen und mir vorher die entry points für wglChoosePixelFormatARB und wglCreateContextAttribsARB von Hand mit wglGetProcAddress besorgt.
Alles ganz toll. glewInit() kommt mit GLEW_OK zurück, GLEW_VERSION_3_3 ist true ... das Leben könnte so schön sein.
Jetzt schmiert mir mein Demo ab weil einzelne Funktionen wie glGenerateMipmap oder glGenFramebuffers auf NULL zeigen, also offenbar nicht initialisiert sind.

Hier meine neue init ...

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
void GL::_EnableOpenGL(HWND hWnd)
{
    int nPixelFormat  = -1;
    PIXELFORMATDESCRIPTOR pfd;
    int format;

    // disable if enabled
    _DisableOpenGL();

    // init win handle
    GL::m_hWnd = hWnd;  

    // get dummy device context (DC)
    GL::m_hDC = GetDC( GL::m_hWnd );
    
    // set dummy pixel format to get dummy render context to init glew
    ZeroMemory( &pfd, sizeof( pfd ) );
    pfd.nSize = sizeof( pfd );
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    format = ChoosePixelFormat( GL::m_hDC, &pfd );
    SetPixelFormat( GL::m_hDC, format, &pfd );
    
    // create and enable dummy render context (RC)
    GL::m_hRC_Dummy = wglCreateContext( GL::m_hDC );
    wglMakeCurrent( GL::m_hDC, GL::m_hRC_Dummy );

    p_wglChoosePixelFormatARB ____wglChoosePixelFormatARB = (p_wglChoosePixelFormatARB)wglGetProcAddress("wglChoosePixelFormatARB");
    if(____wglChoosePixelFormatARB == NULL)
    {
        _DisableOpenGL();
        std::string strMsg;
        strMsg = "Unable to get entry point for wglChoosePixelFormatARB !";
        throw strMsg;
    }

    p_wglCreateContextAttribsARB ____wglCreateContextAttribsARB = (p_wglCreateContextAttribsARB)wglGetProcAddress("wglCreateContextAttribsARB");
    if(____wglCreateContextAttribsARB == NULL)
    {
        _DisableOpenGL();
        std::string strMsg;
        strMsg = "Unable to get entry point for wglCreateContextAttribsARB !";
        throw strMsg;
    }

    // throw away the dummy stuff
    wglMakeCurrent( NULL, NULL );
    wglDeleteContext( GL::m_hRC_Dummy );
    GL::m_hRC_Dummy = NULL;

    // Specify the important attributes we care about
    int nPixCount = 0;
    int pixAttribs[] = { WGL_SUPPORT_OPENGL_ARB,    GL_TRUE,
                         WGL_DOUBLE_BUFFER_ARB,     GL_TRUE,
                         WGL_DRAW_TO_WINDOW_ARB,    GL_TRUE,
                         WGL_ACCELERATION_ARB,      WGL_FULL_ACCELERATION_ARB,
                         WGL_RED_BITS_ARB,          8,
                         WGL_GREEN_BITS_ARB,        8,
                         WGL_BLUE_BITS_ARB,         8,
                         WGL_ALPHA_BITS_ARB,        8,
                         WGL_DEPTH_BITS_ARB,        16,
                         WGL_PIXEL_TYPE_ARB,        WGL_TYPE_RGBA_ARB,
                         0}; // NULL termination

    // Ask OpenGL to find the most relevant format matching our attribs
    // Only get one format back.
    ____wglChoosePixelFormatARB(m_hDC, &pixAttribs[0], NULL, 1, &nPixelFormat, (UINT*)&nPixCount);
    if(nPixelFormat == -1) 
    {
        _DisableOpenGL();
        std::string strMsg;
        strMsg = "Finding a pixel format with the requested attributes failed !";
        throw strMsg;
    }

    // Got a format, now set it as the current one
    SetPixelFormat( m_hDC, nPixelFormat, &pfd );

    GLint attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB,  3,
                       WGL_CONTEXT_MINOR_VERSION_ARB,  3,
                       0 };

    m_hRC = ____wglCreateContextAttribsARB(m_hDC, 0, attribs);
    if (m_hRC == NULL)
    {
        _DisableOpenGL();
        std::string strMsg;
        strMsg = "Creating OpenGL 3.3 context failed !";
        throw strMsg;
    }

    BOOL bRet = wglMakeCurrent( m_hDC, m_hRC );
    if(bRet == FALSE)
    {
        _DisableOpenGL();
        std::string strMsg;
        strMsg = "Setting OpenGL context as current failed ! !";
        throw strMsg;
    }

    // init glew
    GLenum glewInitRet = glewInit();
    if(glewInitRet != GLEW_OK)
    {
        _DisableOpenGL();
        std::string strMsg;
        strMsg = "Initialisation of GLEW failed !";
        throw strMsg;
    }
    
    // check if OpenGL 3.3 core is supported
    if(!GLEW_VERSION_3_3)
    {
        _DisableOpenGL();       
        std::string strMsg;
        strMsg = "OpenGL 3.3 core is not supported on this system !";
        throw strMsg;
    }

    // read OpenGL data
    GL::m_strVendor   = (char*)glGetString(GL_VENDOR);
    GL::m_strRenderer = (char*)glGetString(GL_RENDERER);
    GL::m_strOpenGLVersion  = (char*)glGetString(GL_VERSION);
}


Hilfe !!!! :fie: :fie: :fie: :fie: :fie:
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

28.01.2013, 06:36

Du erzeugst ein Core Profile, womit glGetString(GL_EXTENSIONS), welches seit 3.0 deprecated ist, eben nicht mehr das tut, was du willst. In 3.1 und 3.2 wird automatisch ein Compatible Profile erzeugt, in 3.3 ein Core Profile. Da GLEW aber glGetString(GL_EXTENSIONS) nutzt und du 3.3 willst, findet es die Extension nicht mehr und initialisiert sie nicht.

Zudem:

Zitat

GLEW obtains information on the supported extensions from the graphics driver. Experimental or pre-release drivers, however, might not report every available extension through the standard mechanism, in which case GLEW will report it unsupported. To circumvent this situation, the glewExperimental global switch can be turned on by setting it to GL_TRUE before calling glewInit(), which ensures that all extensions with valid entry points will be exposed. "


Zitat

I add the "glewExperimental= GL_TRUE;" before "glewInit();". Everything is OK.


http://webcache.googleusercontent.com/se…firefox-nightly[/URL]

Etwas Google wäre sicher nicht so schwer gewesen. Das stand alles im ersten Treffer bei Google.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

7

28.01.2013, 06:36

EDIT: Hat sich duch den Post von BlueCobold erledigt !!!
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »stef« (28.01.2013, 06:47)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

28.01.2013, 06:38

Siehe mein Beitrag.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

9

28.01.2013, 06:56

Du erzeugst ein Core Profile, womit glGetString(GL_EXTENSIONS), welches seit 3.0 deprecated ist, eben nicht mehr das tut, was du willst. In 3.1 und 3.2 wird automatisch ein Compatible Profile erzeugt, in 3.3 ein Core Profile. Da GLEW aber glGetString(GL_EXTENSIONS) nutzt und du 3.3 willst, findet es die Extension nicht mehr und initialisiert sie nicht.

War ein Volltreffer ! Hut ab und vielen Dank !

Etwas Google wäre sicher nicht so schwer gewesen. Das stand alles im ersten Treffer bei Google.

Habe ich getan (nach GLEW glGenerateMipmap usw.), da kam nichts dergleichen raus.
Muss aber auch sagen das ich öfter schon daneben gegoggelt habe.
Habe da nicht so das Händchen für die richtigen Schlagwörter.
Aber dafür hat man ja gute Leute im Forum ! :thumbsup:
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

10

28.01.2013, 07:12

Eine Sache noch mal zum Verständnis:

Du erzeugst ein Core Profile, womit glGetString(GL_EXTENSIONS), welches seit 3.0 deprecated ist, eben nicht mehr das tut, was du willst. In 3.1 und 3.2 wird automatisch ein Compatible Profile erzeugt, in 3.3 ein Core Profile. Da GLEW aber glGetString(GL_EXTENSIONS) nutzt und du 3.3 willst, findet es die Extension nicht mehr und initialisiert sie nicht.

glGenerateMipmap oder glGenFramebuffers sind doch gar keine Extensions sonder Teil des 3.3 Core Profiles ?
Warum müssen die Funktionen dann mit glGetString abgefragt und initialisiert werden ?
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Werbeanzeige

Ähnliche Themen