Reputation: 1
Whenever I attempt to call SwapBuffers(), GetLastError() returns 6 / ERROR_INVALID_HANDLE. For a while I have attempted to fix this by rewriting this code in different ways, attempting to find different origins of errors and generally looking at what I could be doing wrong. But, I haven't come to a single conclusion on what is inducing this or what I can do to resolve this.
I have also recognized when I call OpenGL functions such as glUseProgram() and glVertexAttribPointer(), glGetError() returns 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);
}
Code to the game state(where I call gl functions):
#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();
}
Upvotes: 0
Views: 1328
Reputation: 612814
You are calling GetLastError
irrespective of whether or not the previous API call failed. You should only call GetLastError
when the documentation indicates that you should. Typically that is when the return value of the function that you called indicates a failure.
It is perfectly possible for an API call to succeed, and GetLastError
to return a non-zero value. It seems likely that is what is happening here.
Upvotes: 2