Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Failed to activate OpenGL context  (Read 4776 times)

0 Members and 1 Guest are viewing this topic.

milen

  • Newbie
  • *
  • Posts: 8
    • View Profile
Failed to activate OpenGL context
« on: October 23, 2018, 08:32:32 am »
Failed to activate OpenGL context: The handle is invalid.

Hello,
I try to make my simple Chart class for C++ with SFML. The idea is to make simple windows for charts, each in different thread so to not affect the main program.

The problem is that the opened windows must be closed in reverse order - from the last opened to the first. Else the upper error message displays in the console. Seems that the program works, but this message worry me.
I am not C++ developer, so preliminary thank you for any help!

My source is:

MChart.hpp
#pragma once

#include <SFML/Graphics.hpp>
#include <string>


class MChart
{

public:
  MChart(const unsigned int width = 500, const unsigned int height = 500,
         const std::string xlabel = "", const std::string ylabel = "", const std::string title = "");

  ~MChart();

  void set_data_len(unsigned int N);
  void append_data(float x, float y);
  void update_data(unsigned int i, float x, float y);

private:
  static unsigned int fig_num;

  const unsigned int border{10};
  unsigned int width, height;
  const std::string xlabel, ylabel, title;
  unsigned int fig_num_c;

  sf::Thread th;
  bool MustToStop{false};
  bool Stopped{false};

  sf::VertexArray graph{sf::LinesStrip};
  sf::VertexArray box_grid{sf::Lines};

  void run_dis();
};
 

MChart.cpp
#include <string>
#include <iostream>
#include <SFML/Graphics.hpp>
#include "MChart.hpp"


unsigned int MChart::fig_num{1};


MChart::MChart(const unsigned int width, const unsigned int height,
               const std::string xlabel, const std::string ylabel, const std::string title) :
               width{width}, height{height}, xlabel{xlabel}, ylabel{ylabel}, title{title},
               th{&MChart::run_dis, this}
               // the list of initializers is initialized in declaration order in *.hpp file (see -Wreorder)
{
    this->fig_num_c = MChart::fig_num++;
    this->th.launch();
}

MChart::~MChart()
{
    this->MustToStop = true;
    while (!this->Stopped)
        ;
}

void MChart::run_dis()
{
    // Initialize window
    sf::ContextSettings settings;
    settings.antialiasingLevel = 8;
    sf::RenderWindow window{sf::VideoMode(this->width, this->height),
                            std::to_string(this->fig_num_c), sf::Style::Close, settings};
    window.setVerticalSyncEnabled(true);

    // Draw window
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if ((event.type == sf::Event::Closed) ||
                ((event.type == sf::Event::KeyPressed) &&
                 (event.key.code == sf::Keyboard::Escape)))
                window.close();
        }

        if (this->MustToStop)
            window.close();

        window.clear(sf::Color(0, 5, 55));

        window.draw(this->graph);
        window.draw(this->box_grid);

        window.display();
    }

    this->Stopped = true;
}

void MChart::set_data_len(unsigned int N)
{
    this->graph.resize(N);
}

void MChart::append_data(float x, float y)
{
    this->graph.append(sf::Vertex(sf::Vector2f(x, y), sf::Color::Yellow));
}

void MChart::update_data(unsigned int i, float x, float y)
{
    if (i < this->graph.getVertexCount())
        graph[i].position = sf::Vector2f(x, y);
}
 

main.cpp
#include "MChart.hpp"

int main()
{
        MChart ch1, ch2;

        for (int i = 0; i < 300; i++)
        {
                ch1.append_data(i, i);
                ch2.append_data(i, i / 2);
        }
        system("pause");
        return 0;
}
 

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11008
    • View Profile
    • development blog
    • Email
Re: Failed to activate OpenGL context
« Reply #1 on: October 23, 2018, 09:40:54 pm »
Despite not recommending such a threading setup, the code is most likely not working out, because you're initializing the classes in the main thread, but then create the windows in the threads and I don't see an setActive call anywhere.

Also you're nowhere protecting the shared graph data, so you potentially write from your main thread at the same time your read in the threads, which can lead to race conditions or even crashes.

Multi-thread programming is an advanced topic and needs quite some understanding on how to deal with protecting shared resources. Adding OpenGL into the mix makes everything even more complicated.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

milen

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Failed to activate OpenGL context
« Reply #2 on: October 24, 2018, 07:38:48 am »
eXpl0it3r, Thank you for reply.

But I create and use windows only in separate threads. Each window with its event/draw(update) loop is whole in its thread.

I create class in main(), but the windows are created and controller whole locally in function, whole in its self thread.
So one doubtfully thing is updating of Vertex in the main(). So I remove the whole for cycle from main(), so, there are created only two empty windows.
But the problem persists - I must close them in reverse order of the creation - so if I close first the window 1, and then the window 2, then the Error message "Failed to activate OpenGL context: The handle is invalid." is written, but if I close first window 2, than 1 - no message is displayed.

In the two cases the program seems to work properly and the exit code i 0. But this message in the console worry me.
Why the row of creation/closing is important?! The each class has fully independent memory, thread and so on. No any shared resources. I try to use std::thread and the result is the same.