• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed SFML - "An internal OpenGL call failed in Texture.cpp(98)."

0 głosów
2,919 wizyt
pytanie zadane 20 lipca 2018 w C i C++ przez seba1711g Początkujący (350 p.)
zamknięte 21 lipca 2018 przez seba1711g

Witam,

Mam problem z renderowaniem tekstury w moim programie.

Kod:

Klasa Game:

#pragma once
#include <vector>
#include <SFML/Graphics.hpp>

#include "Wall.h"

using namespace std;
using namespace sf;

class Game
{
public:
	Game()
	{
		init();
	}
	void render(RenderWindow &window)
	{
		for (int i = 0; i < walls.size(); i++)
		{
			walls[i].render(window);
		}
	}
private:
	void init()
	{
		{
			newWall({ 0,1000 }, 'd');
			newWall({ 0,744 }, 'g');
		}
	}
	void newWall(Vector2f pos, char type)
	{
		Wall wall(pos, type);
		walls.push_back(wall);
	}
	vector <Wall> walls;

};

Klasa Wall:

#pragma once
#include <SFML/Graphics.hpp>

using namespace sf;

class Wall
{
public:
	Wall(Vector2f pos, char type) // type = 'g' - grass, 'd' - dirt
	{
		/*if (type == 'g')
			wallTexture.loadFromFile("data/wallgrass.png");
		else*/
			wallTexture.loadFromFile("data/walldirt.png");

		wall.setTexture(wallTexture);
		wall.setPosition(pos);
	}
	FloatRect box()
	{
		return wall.getGlobalBounds();
	}
	float left()
	{
		return wall.getPosition().x;
	}
	float top()
	{
		return wall.getPosition().y;
	}
	float right()
	{
		return left() + box().width;
	}
	float bottom()
	{
		return top() + box().height;
	}
        void render(RenderWindow &window)
	{
		window.draw(wall);
	}
private:
	Sprite wall;
	Texture wallTexture;

};

Po odpaleniu aplikacji sprite'y się nie pojawiają, a w konsoli pokazuję się informacja:

"An internal OpenGL call failed in Texture.cpp(98).
Expression:
   glFlush()
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state."

i tak 3 razy... 

Co się stało?

Pozdrawiam wszystkich forumowiczów.

komentarz zamknięcia: Dziękiuję wszystkim za pomoc.

2 odpowiedzi

0 głosów
odpowiedź 20 lipca 2018 przez j23 Mędrzec (195,220 p.)
edycja 20 lipca 2018 przez j23

Internety mówią, że GL_INVALID_OPERATION występuje przy próbie wywołania glFlush pomiędzy wywołaniami glBegin i glEnd. Nie wiem, jakie to ma przełożenie na SFML-a, ale zastanowiłbym się nad zmianą typu wallTexture na std::shared_ptr<Texture>, bo ze źródeł wynika, że błąd występuje przy kopiowaniu tekstury (widocznie kopiuje się w nieodpowiednim momencie).

 

Jeszcze inna opcja: zamiast wspomnianego std::shared_ptr można użyć statycznej std::unordered_map<char, sf::Texture>, która by trzymała wszystkie tekstury wykorzystywane przez obiekty klasy Wall.

0 głosów
odpowiedź 20 lipca 2018 przez criss Mędrzec (172,570 p.)
Zgłoś to do devów SFML.

Co do twojego kodu: ty wiesz, że ładujesz teksture za każdym razem gdy tworzysz nowy obiekt Wall? Nie uważasz, że ładowanie i trzymanie w pamięci N identycznych tesktur, żeby narysować N obiektów jest lekko mówiąc.. mało sprytne?  Załaduj teksture raz skoro i tak wszystko będzie wyglądać tak samo.
komentarz 20 lipca 2018 przez seba1711g Początkujący (350 p.)

Po poprawce

Wall(Vector2f pos, Texture &texture)
	{
		wall.setTexture(texture);
		wall.setPosition(pos);
	}

informacja w konsoli się nie pojawia, ale tekstura wciąż się nie ukazuje. Co może być tego przyczyną?

komentarz 21 lipca 2018 przez criss Mędrzec (172,570 p.)
Domyślnie sprite ma rozmiar 0x0. Musisz ustawić mu jakiś rozmiar. Ustawiając teksture w taki sposób: wall.setTexture(texture, true); ustawisz sprite-owi rozmiar tekstury.

Błąd nie występuje, bo dział się przy kopiowaniu tekstury a teraz tego po prostu nie robisz. IMO i tak fajnie by było zgłosić to developerom.
komentarz 21 lipca 2018 przez monika90 Pasjonat (22,940 p.)
Jego kod był błędny bo sprite używał nieistniejącej tekstury, co tu zgłaszać?
komentarz 21 lipca 2018 przez seba1711g Początkujący (350 p.)
edycja 21 lipca 2018 przez seba1711g

W klasie game jest:

void init()
	{
		{
			Texture grassTexture;
			Texture dirtTexture;
			grassTexture.loadFromFile("data/wallgrass.png");
			dirtTexture.loadFromFile("data/walldirt.png");

			newWall({ 0,1000 }, dirtTexture);
			newWall({ 0,744 }, grassTexture);
		}
	}
	void newWall(Vector2f pos, Texture &texture)
	{
		Wall wall(pos, texture);
		walls.push_back(wall);
	}

Teraz działa, ale tekstura jest cała biała. To błąd pliku, czy coś innego? 

komentarz 21 lipca 2018 przez monika90 Pasjonat (22,940 p.)
grassTexture i dirtTexture muszą istnieć tak długo jak są używane, więc zrób je składowymi klasy Game i pod żadnym pozorem nie kopiuj obiektów klasy Game.

Podobne pytania

0 głosów
0 odpowiedzi 358 wizyt
0 głosów
0 odpowiedzi 473 wizyt
pytanie zadane 25 października 2020 w C i C++ przez Xarcane Początkujący (440 p.)
0 głosów
0 odpowiedzi 436 wizyt
pytanie zadane 26 czerwca 2016 w C i C++ przez katolik6 Dyskutant (8,140 p.)

93,771 zapytań

142,731 odpowiedzi

323,383 komentarzy

63,372 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...