2013-08-16 3 views
1

Предположим, что у меня есть COpenGLControl class downloaded here from codeguru, предполагая, что the first event handler runned when creating the OpenGL window is OnCreate, я попытался догнать ошибки этого класса. вот код, используемый для создания окна в .h и .cpp файлы DIALOG Моего:wglCreateContext исключает исключение INVALID_OPERATION

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

, чтобы знать I подумайте, что была вызвана функция OnCreate. На самом деле, я думаю, что строка кода COpenGLControl m_oglWindow; вызывает эту функцию для вызова! но я не уверен, так что это будет оценено, если вы посоветуете мне об этом?
во всяком случае, я не сделал много изменений к классу:

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); 
} 

Как вы видите, что я написал код GLenum error13 = glGetError(); сразу после hrc = wglCreateContext(hdc);, чтобы поймать любую вероятную ошибку, которую он выбрасывает, и да значение для ошибки13 равно 1282, что означает INVALID_OPERATION, поэтому я думаю, что handle for OpenGL rendering context не создано должным образом!
кроме того, если вы проверите значения hdc и hrc, вы столкнулись с этим:

HDC -> Неиспользуемые = ??? (Ошибка: выражение не может быть оценено)
КПЧ -> неиспользованными = 0

Не могли бы вы помочь мне выяснить, почему это так? и в чем проблема?

ответ

2

Результаты не определены, если вы вызываете функции GL (например, glGetError()), не имея текущего контекста GL.

wglCreateContext() является частью API Win33 (а не API GL) и будет сигнализировать об ошибках, возвращая указатель NULL. Вы можете вызвать функцию Windows API GetLastError(), если вам нужны детали в этом случае, как и в большинстве других функций Windows API.

+0

ОК, тогда вы можете сказать @derhass перед вызовом 'glMakeCurrent' Я не могу вызывать функции с префиксом' gl', и я не могу положиться на результаты. да, пишите, когда я вместо этого использую 'DWORD error13 = GetLastError()', результат равен нулю. Но можете ли вы объяснить мне, почему 'unused' для' hdc' является '??? (выражение не может быть оценено)'? – sepideh

+1

@sepideh: ну, «неиспользуемая» часть звучит так, как будто она не используется. Все, что у вас есть, - это непрозрачный дескриптор, и это не ваше дело, на что указывает этот дескриптор. Если возвращаемые значения не являются «NULL», они действительны. Почему вы думаете, что в этой части есть некоторая ошибка? – derhass

+0

, потому что я пытаюсь удалить часть oglDrawScene этого класса и показать текстуру в окне openGL, но я не могу. – sepideh

2

Не вызывайте функцию API OpenGL, прежде чем у вас есть «текущий контекст» для вызывающего потока в Win32. Операции будут неопределенными.

Для исправления этой проблемы просто переведите вызов на wglMakeCurrent (...) на одну строку, чтобы он добрался до звонка до glGetError (...).

Обратите внимание, что вы должны сделать это для каждого потока, а в Win32 только одному потоку разрешен доступ к контексту OpenGL в любой момент времени. Если вы когда-либо захотите сделать многопоточную визуализацию в Win32, вам придется либо приобретать/освобождать контекст, либо выполнять синхронизацию между потоками, либо использовать кучу контекстов, которые «обмениваются списками» (wglShareLists (...)).

Как указано выше, если вы хотите получить информацию об ошибке, созданной WGL API, используйте GetLastError (...). WGL является частью оконной системы, которая построена поверх API Win32, поэтому она будет передавать свои ошибки вам через традиционные каналы Win32.


Кстати, постарайтесь не печатать значения ошибки GL в десятичной форме. Они всегда перечислены в gl.h шестнадцатеричные константы, так что было бы легче найти подходящий enumerant если вы сделали это:

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

То же самое касается всех перечисленных констант в OpenGL. Если у вас нет функции, которая будет отображать их в удобочитаемую строку, вы должны использовать шестнадцатеричное значение, чтобы просмотреть их.

Смежные вопросы