GetLastError() возвращает ERROR_INVALID_HANDLE / 6 после вызова SwapBuffers(HDC)
Всякий раз, когда я пытаюсь вызвать SwapBuffers(), GetLastError() возвращает 6 / ERROR_INVALID_HANDLE. Некоторое время я пытался исправить это, переписывая этот код по-разному, пытаясь найти разные источники ошибок и вообще глядя на то, что я мог делать неправильно. Но я не пришел к единому выводу о том, что побуждает это или что я могу сделать, чтобы решить это.
Я также узнал, когда я вызываю функции OpenGL, такие как glUseProgram() и glVertexAttribPointer(), glGetError() возвращает 1282 / GL_INVALID_OPERATION.
Window::Window(string title, int xPos, int yPos, int width, int height, string icon_path)
{
this->title = title;
this->width = width;
this->height = height;
if (this->height == 0)
this->height = 1;
if (!Create(xPos, yPos))
{
cout << "Window Creation Failure!" << endl;
exit(EXIT_FAILURE);
}
HANDLE hIcon = LoadImage(0, icon_path.c_str(), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
Window::~Window()
{
wglMakeCurrent(hDC, 0);
wglDeleteContext(hRC);
ReleaseDC(hWnd, hDC);
}
bool Window::Create(int xPos, int yPos)
{
WNDCLASS WndClass;
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX;
this->hInstance = GetModuleHandle(nullptr);
if (!this->hInstance)
return false;
WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
WndClass.lpfnWndProc = (WNDPROC) WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = this->hInstance;
WndClass.hIcon = LoadIcon(nullptr, IDI_WINLOGO);
WndClass.hCursor = LoadCursor(nullptr, IDC_ARROW);
WndClass.hbrBackground = nullptr;
WndClass.lpszMenuName = nullptr;
WndClass.lpszClassName = this->title.c_str();
if (!RegisterClass(&WndClass))
return false;
this->hWnd = CreateWindowEx(dwExStyle, this->title.c_str(), this->title.c_str(), dwStyle,
xPos, yPos, this->width, this->height, nullptr, nullptr, this->hInstance, nullptr);
if (!this->hWnd)
return false;
if (!this->CreateContext())
return false;
ShowWindow(this->hWnd, SW_SHOW);
UpdateWindow(this->hWnd);
return true;
}
bool Window::CreateContext()
{
this->hDC = GetDC(hWnd);
if (!this->hDC)
return false;
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
int nPixelFormat = ChoosePixelFormat(this->hDC, &pfd);
if (!nPixelFormat)
return false;
bool bResult = SetPixelFormat(this->hDC, nPixelFormat, &pfd);
if (!bResult)
return false;
HGLRC tempOpenGLContext = wglCreateContext(this->hDC);
wglMakeCurrent(this->hDC, tempOpenGLContext);
GLenum err = glewInit();
if (GLEW_OK != err)
return false;
int attributes[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
0
};
if (wglewIsSupported("WGL_ARB_create_context") == true)
{
this->hRC = wglCreateContextAttribsARB(this->hDC, NULL, attributes);
wglMakeCurrent(nullptr, nullptr);
wglDeleteContext(tempOpenGLContext);
wglMakeCurrent(this->hDC, this->hRC);
if (!this->hRC)
return false;
}
else
{
this->hRC = tempOpenGLContext;
}
int glVersion[2] = {-1, -1};
glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]);
glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]);
cout << "Opengl is running on context version : " << glVersion[0] << ", " << glVersion[1] << endl;
return true;
}
int Window::GameLoop(Core *core)
{
MSG msg;
while (core->IsRunning())
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
core->SetRunning(false);
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
core->Run();
SwapBuffers(this->hDC);
}
}
Core::Destroy();
return (int)(msg.wParam);
}
Код состояния игры (где я вызываю функции gl):
#include "State.h"
using namespace Lumen::Core_Engine;
GLfloat Data[9] =
{
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
Example::Example()
{
this->colourShader = new Shader("./Shaders/Vertex/BasicColour.vert", "./Shaders/Vertex/BasicColour.vert");
this->colourVertexArray = new VertexArray(new VertexBuffer(Data, sizeof(Data), GL_TRIANGLES, 3, sizeof(GLfloat) * 3, this->colourShader));
cout << "'Example' state initialized!" << endl;
}
Example::~Example()
{
}
void Example::Update()
{
GLenum errGL = glGetError();
if (GLEW_NO_ERROR != errGL)
cout << errGL << endl;
DWORD errWin = GetLastError();
if (NO_ERROR != errWin)
cout << errWin << endl;
}
void Example::Render()
{
glUseProgram((colourVertexArray->GetVertexBufferObject()->GetShader())->GetProgram());
(colourVertexArray->GetVertexBufferObject()->GetShader())->SetFloat4((colourVertexArray->GetVertexBufferObject()->GetShader())->GetUniform("Colour"), 1.0f, 0.0f, 0.0f, 1.0f);
(colourVertexArray)->AddVertexBufferObjectTarget((colourVertexArray->GetVertexBufferObject()->GetShader())->GetAttribute("Position"));
(colourVertexArray)->Render();
}
1 ответ
Ты звонишь GetLastError
независимо от того, был ли сбой предыдущего вызова API. Вы должны только позвонить GetLastError
когда документация указывает, что вы должны. Обычно это когда возвращаемое значение функции, которую вы вызвали, указывает на ошибку.
Для вызова API вполне возможно, и GetLastError
вернуть ненулевое значение. Кажется вероятным, что это то, что здесь происходит.