samedi 30 mai 2015

GetLastError() returns ERROR_INVALID_HANDLE / 6 after calling SwapBuffers(HDC)

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.

I'm thankful for any replies.

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

Aucun commentaire:

Enregistrer un commentaire