wglCreateContext 抛出 INVALID_OPERATION 异常
Posted
技术标签:
【中文标题】wglCreateContext 抛出 INVALID_OPERATION 异常【英文标题】:wglCreateContext throws INVALID_OPERATION exception 【发布时间】:2013-08-16 18:47:05 【问题描述】:假设我有COpenGLControl class downloaded here from codeguru 假设the first event handler runned when creating the OpenGL window is OnCreate,我试图赶上这个类的错误。这是用于在我的对话框的 .h 和 .cpp 文件中创建窗口的代码:
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);
知道我认为函数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);
如您所见,我在hrc = wglCreateContext(hdc);
之后编写了代码GLenum error13 = glGetError();
以捕获它抛出的任何可能的错误,是的,error13 的值是1282
这意味着INVALID_OPERATION
所以我认为handle for OpenGL rendering context
是没有正确创建!
此外,如果您检查 hdc
和 hrc
的值,您会遇到这些:
hdc -> 未使用 = ??? (错误:无法计算表达式) hrc -> 未使用 = 0
您能帮我找出原因吗?还有什么问题?
【问题讨论】:
【参考方案1】:如果您在没有当前 GL 上下文的情况下调用 GL 函数(如 glGetError()
本身),则结果非常不确定。
wglCreateContext()
是 Win33 API(而不是 GL API)的一部分,将通过返回 NULL
指针来指示错误。如果您需要这种情况下的详细信息,可以调用 Windows API 函数 GetLastError()
,就像大多数其他 Windows API 函数一样。
【讨论】:
好的,那么@derhass 你的意思是在调用glMakeCurrent
之前我不能调用前缀为gl
的函数,我不能依赖结果。是的,当我改用DWORD error13 = GetLastError()
时,你写的结果为零。但是你能解释一下为什么hdc
的unused
是???(the expression can not be evaluated)
吗?
@sepideh:好吧,“未使用”部分听起来很像未使用。你得到的只是一些不透明的句柄,你不关心这个句柄实际指向的地方。如果返回值不是NULL
,则有效。为什么你认为这部分有一些错误?
因为有一段时间我正在尝试删除此类的 oglDrawScene 部分并在 openGL 窗口上显示纹理,但我不能。
@sepideh:不过,为什么您认为存在与 GL 上下文创建直接相关的问题?
没有什么只是想从一开始就研究课程,看看课程本身是否有任何错误,因为我的老师在我的纹理相关代码中找不到错误。【参考方案2】:
在 Win32 中的调用线程拥有“当前上下文”之前,不要调用 OpenGL API 函数。操作将是未定义的。
要更正此问题,只需将呼叫wglMakeCurrent (...)
移动一行,使其位于呼叫glGetError (...)
之前。
请注意,您必须为每个线程执行此操作,并且在 Win32 中,在任何给定时间只允许一个线程访问 OpenGL 上下文。如果您想在 Win32 中进行多线程渲染,您将不得不获取/释放上下文并在线程之间进行同步,或者使用一堆“共享列表”的上下文 (wglShareLists (...)
)。
就像 derhass 提到的,如果您想了解有关 WGL API 生成的错误的信息,请使用 GetLastError (...)
。 WGL 是窗口系统的一部分,它建立在 Win32 API 之上,因此它会通过传统的 Win32 渠道将其错误传达给您。
顺便说一句,尽量不要以十进制形式打印 GL 错误值。它们总是在 gl.h 中作为十六进制常量枚举,因此如果您这样做会更容易找到合适的枚举数:
printf ("OpenGL Error: 0x%X\n", err);
OpenGL 中的所有枚举常量也是如此。如果您没有将它们映射到人类可读字符串的函数,则应使用十六进制值来查找它们。
【讨论】:
以上是关于wglCreateContext 抛出 INVALID_OPERATION 异常的主要内容,如果未能解决你的问题,请参考以下文章
exception2:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd7 in position 0: inval
homestead的laravel项目错误:Use of undefined constant JSON_INVALID_UTF8_SUBSTITUTE - assumed ‘JSON_INVAL(代
Mysql5.7.11 安装 cacti0.8.8f ,在导入cacti.sql数据库时出现下记错误,导致数据库导入终止: ERROR 1067 (42000) at line 1847: Inval