Question

suppose that I have COpenGLControl class downloaded here from codeguru assuming that the first event handler runned when creating the OpenGL window is OnCreate, I have tried to catch up the errors of this class. here's the code used to create the window in my dialog's .h and .cpp files:

MyOpenGLTestDlg.h

COpenGLControl m_oglWindow;  

MyOpenGLTestDlg.cpp

CRect rect;

// Get size and position of the picture control
GetDlgItem(ID_OPENGL)->GetWindowRect(rect);

// Convert screen coordinates to client coordinates
ScreenToClient(rect);  

up to know I think the function OnCreate has been invoked. In fact, I think the line of code COpenGLControl m_oglWindow; causes this function to be invoked! but I'm not sure so it will be appreciated if you guide me alittle about this?
anyway, I have not made a lot of change to the class:

OpenGLControl.h

#pragma once
#include "afxwin.h"
#include "WinBase.h"

#include <gl/gl.h>
#include <gl/glu.h>

class COpenGLControl : public CWnd
{
public:
    /******************/
    /* Public Members */
    /******************/
    UINT_PTR m_unpTimer;
    // View information variables
    float    m_fLastX;
    float    m_fLastY;
    float    m_fPosX;
    float    m_fPosY;
    float    m_fZoom;
    float    m_fRotX;
    float    m_fRotY;
    bool     m_bIsMaximized;

private:
    /*******************/
    /* Private Members */
    /*******************/
    // Window information
    CWnd  *hWnd;     //window handle
    HDC   hdc;       //device context handle    
    HGLRC hrc;       //handle to GL Rendering Context
    int   m_nPixelFormat;
    CRect m_rect;
    CRect m_oldWindow;
    CRect m_originalRect;

public:
    COpenGLControl(void);
    virtual ~COpenGLControl(void);

    void oglCreate(CRect rect, CWnd *parent);
    void oglInitialize(void);
    void oglDrawScene(void);

    // Added message classes:
    afx_msg void OnPaint();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnDraw(CDC *pDC);
    afx_msg int  OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnTimer(UINT nIDEvent);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);

    DECLARE_MESSAGE_MAP()
};  

OpenGLControl.cpp

int COpenGLControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;

    oglInitialize();

    return 0;
}  
void COpenGLControl::oglInitialize(void)
{
    // Initial Setup:
    //
    static PIXELFORMATDESCRIPTOR pfd =
    {
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,
        32, // bit depth
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        24, // z-buffer depth
        8,0,PFD_MAIN_PLANE, 0, 0, 0, 0,
    };

    // Get device context only once.
    hdc = GetDC()->m_hDC;
    // Pixel format.
    m_nPixelFormat = ChoosePixelFormat(hdc, &pfd);
    SetPixelFormat(hdc, m_nPixelFormat, &pfd);
    // Create the OpenGL Rendering Context.
    hrc = wglCreateContext(hdc);
    GLenum error13 = glGetError();
    wglMakeCurrent(hdc, hrc);

   // Basic Setup:
   //
   // Set color to use when clearing the background.
   glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
   glClearDepth(1.0f);
   // Turn on backface culling
   glFrontFace(GL_CCW);
   glCullFace(GL_BACK);
   // Turn on depth testing
   glEnable(GL_DEPTH_TEST);
   glDepthFunc(GL_LEQUAL);
   // Send draw request
   OnDraw(NULL);
}  

As you see I have written the code GLenum error13 = glGetError(); right after hrc = wglCreateContext(hdc); to catch any probable error that it throws and yes the value for error13 is 1282 which means INVALID_OPERATION so I think the handle for OpenGL rendering context is not created properly!
besides if you check the values for hdc and hrc, you encounter these:

hdc -> unused = ??? (Error: expression can not be evaluated)
hrc -> unused = 0

Could you help me find out why it is the case? and what's the problem?

Was it helpful?

Solution

The results are quite undefined if you call GL functions (like glGetError() itself) without having a current GL context.

wglCreateContext() is part of the Win33 API (and not the GL API) and will signal errors by returning a NULL pointer. You can call the Windows API function GetLastError() if you want details in that case, like with most other Windows API functions.

OTHER TIPS

Do not call an OpenGL API function before you have a "current context" for the calling thread in Win32. The operations will be undefined.

To correct this issue, simply move the call to wglMakeCurrent (...) one line up so that it comes before the call to glGetError (...).

Note that you have to do this for every thread, and in Win32 only one thread is allowed to access an OpenGL context at any given time. If you ever want to do multi-threaded rendering in Win32, you will have to either acquire/release the context and do synchronization between threads or use a bunch of contexts that "share lists" (wglShareLists (...)).

Like derhass mentioned, if you want information about an error generated by the WGL API, use GetLastError (...). WGL is part of the window system, which is built on top of the Win32 API, so it will communicate its errors to you through the traditional Win32 channels.


By the way, try not to print GL error values in decimal form. They are always enumerated in gl.h as hexadecimal constants, so it would be easier to find the appropriate enumerant if you did this:

printf ("OpenGL Error: 0x%X\n", err);

The same goes for all enumerated constants in OpenGL. If you do not have a function that will map them to a human-readable string, you should use the hexadecimal value to look them up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top