Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Rendu avec un autre thread et matrice de vue opengl.  (Lu 3411 fois)

0 Membres et 1 Invité sur ce sujet

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Rendu avec un autre thread et matrice de vue opengl.
« le: Novembre 02, 2013, 12:28:10 pm »
Salut,
j'ai une question en ce qui concerne opengl, ou est ce que je dois charger les matrices lorsque j'effectue un rendu avec un autre thread, car, lorsque je charge les matrices dans le thread principal, cela ne marche plus lorsque j'ai lancé mon thread de rendu, j'ai donc du charger la matrice de vue dans mon thread de rendu.

#include "render3DWindow.h"
#include <SFML/OpenGL.hpp>
using namespace std;
using namespace sf;
Render3DWindow::Render3DWindow(Vec2f size, std::string title, ContextSettings settings) : Window(VideoMode(size.x, size.y), title, Style::Default, settings), view3D(size.x, size.y, 70, 500, Vec3f(0, 1,0)) {
    running = false;
    view3D.move(0, 0, 10);
}

void Render3DWindow::show () {


    running = true;
    setActive(false);
    m_thread = thread (&Render3DWindow::run, this);
    while(isOpen()) {

        sf::Event event;
        while (pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                // on stoppe le programme
                running = false;
            }
            else if (event.type == sf::Event::Resized)
            {
                // on ajuste le viewport lorsque la fenêtre est redimensionnée
                glViewport(0, 0, event.size.width, event.size.height);
            }
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
            view3D.move(view3D.getForward(), 0.1f);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
            view3D.move(view3D.getForward(), -1);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
            view3D.move(view3D.getLeft(), 1);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
             view3D.move(view3D.getLeft(), -1);
        }
    }
}
void Render3DWindow::run() {
    setActive(true);
    glEnable(GL_DEPTH_TEST);
    while (running)
    {
        // effacement les tampons de couleur/profondeur

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        ViewMatrix vm = view3D.getViewMatrix();
        float matrix[16];
        vm.getGlMatrix(matrix);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glLoadMatrixf(matrix);
        glBegin(GL_QUADS);

        glColor3ub(255,0,0); //face rouge
        glVertex3d(-1,1,1);
        glVertex3d(1,1,1);
        glVertex3d(1,-1,1);
        glVertex3d(-1,-1,1);


        glColor3ub(0,0,255); //face bleue
        glVertex3d(-1, 1, -1);
        glVertex3d(1, 1, -1);
        glVertex3d(1,-1, -1);
        glVertex3d(-1, -1, -1);

        glColor3ub(0,255,0); //face verte
        glVertex3d(1, 1, 1);
        glVertex3d(1, 1, -1);
        glVertex3d(1,-1, -1);
        glVertex3d(1, -1, 1);

        glColor3ub(255,255,0); //face jaune
        glVertex3d(-1,1,1);
        glVertex3d(-1,1,-1);
        glVertex3d(-1,-1,-1);
        glVertex3d(-1,-1,1);

        glColor3ub(0,255,255); //face cyan
        glVertex3d(1,-1,1);
        glVertex3d(1,-1,-1);
        glVertex3d(-1,-1,-1);
        glVertex3d(-1,-1,1);

        glColor3ub(255,0,255); //face magenta
        glVertex3d(1,1,1);
        glVertex3d(1,1,-1);
        glVertex3d(-1,1,-1);
        glVertex3d(-1,1,1);
        glEnd();
        display();
    }

}
 

Est ce bon comme ça ou bien il y a t'il une autre méthode ?

PS : j'ai vu ta classe view et je doute que la vue se déplace vraiment si on fait un rendu en utilisant un autre thread...., je n'ai jamais essayé mais...
« Modifié: Novembre 02, 2013, 12:37:16 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Rendu avec un autre thread et matrice de vue opengl.
« Réponse #1 le: Novembre 02, 2013, 06:52:05 pm »
C'est pas une histoire de thread, mais de contexte OpenGL. Lorsque tu fais un truc il faut que tu aie le bon contexte OpenGL activé, c'est tout.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Rendu avec un autre thread et matrice de vue opengl.
« Réponse #2 le: Novembre 02, 2013, 07:43:27 pm »
Quand je crée un autre thread il me crée aussi un autre contexte opengl c'est ça ???

Sinon comment faire pour activer le bon contexte opengl dans mon thread de rendu ? (Parce que apparemment ce n'est pas le bon)

« Modifié: Novembre 02, 2013, 07:45:04 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Rendu avec un autre thread et matrice de vue opengl.
« Réponse #3 le: Novembre 02, 2013, 08:47:26 pm »
Il suffit d'appeler setActive(true) pour activer un contexte.

Il faudrait que tu nous montres un code complet minimal qui reproduit le problème, là il est difficile de conclure avec le code que tu montres. Rien n'a l'air louche.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Rendu avec un autre thread et matrice de vue opengl.
« Réponse #4 le: Novembre 02, 2013, 09:10:13 pm »
J'ai une question : est ce que je peux remettre le setActive à true après que j'ai lancer mon thread de rendu dans le thread principal ?
C'est juste au lancement du thread de rendu qu'il faut désactivé le context opengl ?

PS : j'ai lu ça dans le tutoriel qu'il faut le désactiver avant de lancer le thread de rendu sinon ça marche pas.

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Rendu avec un autre thread et matrice de vue opengl.
« Réponse #5 le: Novembre 02, 2013, 09:54:35 pm »
Mwai non ça ne marche pas il faut absolument que le contexte opengl soit désactivé dans le boucle de gestion des évènements... (donc, dans le thread principal quoi)

Et que je récupère le contexte opengl dans la boucle de rendu à chaque fois. (donc, dans l'autre thread)
Vu que je fais les déplacement de la caméra dans la boucle principale..., et que je ne peux pas activer le contexte opengl et charger la matrice de vue dans cette boucle...


« Modifié: Novembre 02, 2013, 09:58:23 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Rendu avec un autre thread et matrice de vue opengl.
« Réponse #6 le: Novembre 02, 2013, 11:12:36 pm »
Un contexte OpenGL ne peut être actif que dans un thread à la fois. Mais pourquoi en as-tu besoin dans ton thread principal ?
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Rendu avec un autre thread et matrice de vue opengl.
« Réponse #7 le: Novembre 03, 2013, 09:17:21 am »
A vrai dire je voulais charger la matrice à chaque fois que je me déplaçais dans le monde avec cette classe-ci  pour éviter de devoir le faire à chaque rendu :

#include "3DView.h"
#include <SFML/OpenGL.hpp>
View3D::View3D (double width, double height, double depth, Vec3f up) {
    glViewport(0, 0, width, height);
    setPerspective(-width * 0.5f, width * 0.5f, -height * 0.5f, height * 0.5f, 1, depth);

    this->up = up;
    Vec3f v1 (up.x, up.y, 0);
    Vec3f v2 (0, up.y, up.z);
    position = Vec3f (0, 0, 0);
    teta = phi = 0.f;
    gamma = v1.getAngleBetween(Vec3f::yAxis, Vec3f::zAxis);
    phi2 = v2.getAngleBetween(Vec3f::yAxis, Vec3f::zAxis);
    zoomFactor = 1.f;
    forward = Math::toCartesian(Math::toRadians(phi), Math::toRadians(teta));
    left = up.cross(forward).normalize();
    target = position + forward;
    Vec3f angles (-(phi + phi2), -teta, -gamma);
    viewMatrix.setRotation(angles);
    viewMatrix.setScale(Vec3f(zoomFactor, zoomFactor, zoomFactor));
    viewMatrix.setTranslation(Vec3f(-position.x, -position.y, -position.z));
    float matrix[16];
    viewMatrix.getGlMatrix(matrix);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLoadMatrixf(matrix);
}
View3D::View3D (double width, double height, double fovy, double depth, Vec3f up) {
    glViewport(0, 0, width, height);
    setPerspective(-width * 0.5f, width * 0.5f, -height * 0.5f, height * 0.5f, fovy, width / height, 1, depth);
    this->up = up;
    Vec3f v1 (up.x, up.y, 0);
    Vec3f v2 (0, up.y, up.z);
    position = Vec3f (0, 0, 0);
    teta = phi = 0.f;
    gamma = v1.getAngleBetween(Vec3f::yAxis, Vec3f::zAxis);
    phi2 = v2.getAngleBetween(Vec3f::yAxis, Vec3f::zAxis);
    zoomFactor = 1.f;
    forward = Math::toCartesian(Math::toRadians(teta), Math::toRadians(phi));
    left = up.cross(forward).normalize();
    target = position + forward;
    Vec3f angles (-(phi + phi2), -teta, -gamma);

    viewMatrix.setRotation(angles);
    viewMatrix.setScale(Vec3f(zoomFactor, zoomFactor, 1));
    viewMatrix.setTranslation(Vec3f(-position.x, -position.y, -position.z));
    float matrix[16];
    viewMatrix.getGlMatrix(matrix);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLoadMatrixf(matrix);
}
void View3D::move(float x, float y, float z) {
    position += Vec3f (x, y, z);
    target = position + forward;
    viewMatrix.setTranslation(Vec3f (-position.x, -position.y, -position.z));
    viewMatrix.setOrigin(position);
    float matrix[16];
    viewMatrix.getGlMatrix(matrix);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLoadMatrixf(matrix);
}
void View3D::move (Vec3f dir, float delta) {
    position += dir * delta;
    target = position + forward;
    viewMatrix.setTranslation(Vec3f (-position.x, -position.y, -position.z));
    viewMatrix.setOrigin(position);
    float matrix[16];
    viewMatrix.getGlMatrix(matrix);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLoadMatrixf(matrix);
}
ViewMatrix View3D::getViewMatrix() {
    return viewMatrix;
}
Vec3f View3D::getLeft() {
    return left;
}
Vec3f View3D::getUp() {
    return up;
}
Vec3f View3D::getForward() {
    return forward;
}
float View3D::getTeta() {
    return teta;
}
float View3D::getPhi() {
    return phi;
}
void View3D::computeVectorsFromAngles() {
    forward = Math::toCartesian(Math::toRadians(teta), Math::toRadians(phi));
    left = up.cross(forward).normalize();
    target = position + forward;
}
void View3D::computeAnglesFromVectors () {
    float r = forward.magnitude();
    Vec2f xy (forward.x, forward.z);
    Vec2f yz (forward.y, -Math::abs(forward.z));
    teta = xy.getAngleBetween(Vec2f(0, -1));
    phi = yz.getAngleBetween(Vec2f(0, -1));
}
void View3D::lookAt(float x, float y, float z) {
    target = Vec3f(x, y, z);
    forward = target - position;
    left = up.cross(forward).normalize();
    computeAnglesFromVectors();
    Vec3f angles (-(phi + phi2), -teta, -gamma);
    viewMatrix.setRotation(angles);
    viewMatrix.setOrigin(position);
    float matrix[16];
    viewMatrix.getGlMatrix(matrix);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLoadMatrixf(matrix);
}
void View3D::rotate(float teta, float phi) {
    if (phi > 90)
        phi = 90;
    if (phi < -90)
        phi = -90;
    this->phi = phi;
    this->teta = teta;
    computeVectorsFromAngles();
    Vec3f angles (-(phi + phi2), -teta, -gamma);
    viewMatrix.setRotation(angles);
    float matrix[16];
    viewMatrix.getGlMatrix(matrix);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLoadMatrixf(matrix);
}
void View3D::zoom (float zoom) {
    zoomFactor = zoom;
    viewMatrix.setScale(Vec3f(zoomFactor, zoomFactor, zoomFactor));
    float matrix[16];
    viewMatrix.getGlMatrix(matrix);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLoadMatrixf(matrix);
}
void View3D::setPerspective (double left, double right, double bottom, double top, double front, double back) {
    if (front < 0)
        front = -front;
    if (back < 0)
        back = -back;
    projMatrix.setGlOrthoMatrix(left, right, bottom, top, front, back);
    float matrix[16];
    projMatrix.getGlMatrix(matrix);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum (left, right, bottom, top, front, back);
    glLoadMatrixf (matrix);
}
void View3D::setPerspective(double left, double right, double bottom, double top, double fovy, double aspect, double front, double back) {
    if (front < 0)
        front = -front;
    if (back < 0)
        back = -back;
    double tangent = Math::tang(Math::toRadians(fovy) * 0.5f);   // tangent of half fovY
    double hheight = front * tangent;          // half height of near plane
    double hwidth = hheight * aspect;
    projMatrix.setGlPerspectiveMatrix(left, right, bottom, top, front, back);
    float matrix[16];
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum (-hwidth, hwidth, -hheight, hheight, front, back);
    projMatrix.getGlMatrix(matrix);
    glLoadMatrixf(matrix);
}
 

Mais comme je suis soumis à cette contrainte "le contexte opengl ne peut être actif que dans un seul thread à la fois" : je suis obligé de charger la matrice à chaque rendu dans mon thread de rendu.

Et pas dans les fonctions move, rotate, etc... de la classe view3D qui sont appelée dans le thread main, dans la boucle de gestion d’évènement.

Je me demandais si il y avait une alternative qui me pemettrait d'éviter de devoir charger la matrice à chaque rendu en utilisant 1 thread pour le rendu mais apparemment non.


Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Rendu avec un autre thread et matrice de vue opengl.
« Réponse #8 le: Novembre 03, 2013, 10:09:04 am »
C'était de toute façon une mauvaise idée de vouloir faire comme ça. Regroupe tous les appels OpenGL dans le même thread. Y a pas vraiment d'inconvénient à charger la matrice de vue dans le thread de rendu, je ne sais pas pourquoi tu voulais faire autrement.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Rendu avec un autre thread et matrice de vue opengl.
« Réponse #9 le: Novembre 03, 2013, 02:14:14 pm »
Ha je sais comment je vais faire, avec une variable booléenne que je remettrai à jour si la caméra à bougé, alors je recharge la matrice dans le thread de rendu.

Juste pour information c'est pour un nouveau projet : une extension de la SFML pour faire de la 3D. (J'ouvrirai un topic quand j'aurai terminé parce que là je dois recoder certaines classes du module graphique SFML)



 

anything