1
Graphique / SFML + OpenGL, violation droit d'accès.
« le: Mai 29, 2015, 10:47:12 pm »
Bonsoir,
j'essaye d'utiliser OpenGL en même temps que la SFML, et me heurte à un problème : quand je mixe les dessins OpenGL et le dessin d'un texte SFML, le programme plante et une erreur "violation du droit d'accès" surgit. Après quelques recherches sur internet, j'ai trouvé que la fonction pushGLStates() de la SFML ne réinitialisait pas tous les attributs (ou buffers) d'OpenGL, et que du coup, cela pouvait influer sur les dessins OpenGL ensuite. Le soucis est que je ne vois pas comment régler ce problème.
J'ai réussi à reproduire le problème dans un code à peu près minimal. Je retire également toutes les parties qui ne relèvent pas du sujet comme le chargement des polices d'écriture ou le chargement d'un programme OpenGL (via la classe Locator), qui fonctionnent très bien.
Quelques captures d'écran que j'obtiens :
- L'erreur en elle-même (et le programme plante sur la ligne "glDrawArrays(GL_TRIANGLES, 0, 3);")
- Ce que j'obtiens si jamais je retire le code de dessin du texte SFML (tout fonctionne) :
- Et enfin, ce que j'obtiens si jamais je mets le code de dessin OpenGL en commentaire :
Pour ce dernier point, on peut voir qu'il y a un avertissement dans la console. J'ai lu que cela avait été déjà fixé, donc passons, mais je pense que les problèmes sont liés.
En espérant que vous puissiez m'aider, merci d'avance.
j'essaye d'utiliser OpenGL en même temps que la SFML, et me heurte à un problème : quand je mixe les dessins OpenGL et le dessin d'un texte SFML, le programme plante et une erreur "violation du droit d'accès" surgit. Après quelques recherches sur internet, j'ai trouvé que la fonction pushGLStates() de la SFML ne réinitialisait pas tous les attributs (ou buffers) d'OpenGL, et que du coup, cela pouvait influer sur les dessins OpenGL ensuite. Le soucis est que je ne vois pas comment régler ce problème.
J'ai réussi à reproduire le problème dans un code à peu près minimal. Je retire également toutes les parties qui ne relèvent pas du sujet comme le chargement des polices d'écriture ou le chargement d'un programme OpenGL (via la classe Locator), qui fonctionnent très bien.
#include <SFML/Graphics.hpp>
#include "Locator.h"
#include <GL/glew.h>
#include <SFML/OpenGL.hpp>
#include <GL/glut.h>
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
int main(void)
{
sf::RenderWindow _window(sf::VideoMode(860, 680), "Terrain Generator");
// Initialise glew.
glewInit();
// La police de caractère pour l'affichage des FPS.
sf::Font _fpsFont;
// Le texte qui montre les FPS à l'écran.
sf::Text _fpsCounter;
// Retiré : chargement de la police et paramètrage du texte pour qu'il affiche "0.00"
// en haut à gauche de l'écran, en blanc.
sf::CircleShape circleShape(50.f);
circleShape.setPosition(sf::Vector2f(100., 100.));
GLuint VertexArrayID;
GLuint vertexbuffer;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// Boucle de jeu
while (_window.isOpen()) {
// Evenements
sf::Event event;
while (_window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
_window.close();
}
}
// Dessin
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// ----- OPENGL
glUseProgram(Locator::getShaderLoader().getProgram(Resources::Shader::Triangle));
// 1er attribut du buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// Dessine le triangle
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
// ----- SFML
_window.pushGLStates();
_window.draw(_fpsCounter);
_window.draw(circleShape);
_window.popGLStates();
_window.display();
}
return 0;
}
#include "Locator.h"
#include <GL/glew.h>
#include <SFML/OpenGL.hpp>
#include <GL/glut.h>
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
int main(void)
{
sf::RenderWindow _window(sf::VideoMode(860, 680), "Terrain Generator");
// Initialise glew.
glewInit();
// La police de caractère pour l'affichage des FPS.
sf::Font _fpsFont;
// Le texte qui montre les FPS à l'écran.
sf::Text _fpsCounter;
// Retiré : chargement de la police et paramètrage du texte pour qu'il affiche "0.00"
// en haut à gauche de l'écran, en blanc.
sf::CircleShape circleShape(50.f);
circleShape.setPosition(sf::Vector2f(100., 100.));
GLuint VertexArrayID;
GLuint vertexbuffer;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// Boucle de jeu
while (_window.isOpen()) {
// Evenements
sf::Event event;
while (_window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
_window.close();
}
}
// Dessin
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// ----- OPENGL
glUseProgram(Locator::getShaderLoader().getProgram(Resources::Shader::Triangle));
// 1er attribut du buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// Dessine le triangle
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
// ----- SFML
_window.pushGLStates();
_window.draw(_fpsCounter);
_window.draw(circleShape);
_window.popGLStates();
_window.display();
}
return 0;
}
Quelques captures d'écran que j'obtiens :
- L'erreur en elle-même (et le programme plante sur la ligne "glDrawArrays(GL_TRIANGLES, 0, 3);")
(click to show/hide)
(click to show/hide)
(click to show/hide)
En espérant que vous puissiez m'aider, merci d'avance.