LINUX.ORG.RU

Проблема с окном OpenGL в Qt


0

1

Здравствуйте. Пишу программу, в которой при нажатии на кнопку должно появляться окно с выводом 3d изображения. Возникла такая проблема: при нажатии на кнопку, которая должна открыть окно ничего не происходит (присмотревшись при множественном нажатии заметил, что окно открывается и сразу же закрывается).

По нажатию кнопки:

    graf3d graf;
    graf.show();

graf3d.h:


#ifndef SCENE3D_H
#define SCENE3D_H

#include <QtGui/QWidget>
#include <QtOpenGL>

class graf3d: public QGLWidget
{
    Q_OBJECT

public:
    graf3d(QWidget *parent = 0);
    ~graf3d();
    void set_param(int,int);

    GLfloat ***VertexArray; // декларируем массив вершин
    GLfloat **ColorArray;  // декларируем массив цветов
private:
    GLfloat xRot, yRot, zRot; // переменные углов поворта
    GLfloat nSca; //переменная отвечающая за масштаб объекта
    GLfloat zTra; // величина трансляции оси Z
    int ng,nv;

    QPoint ptrMousePosition; // координаты мыши при нажатии

    void scale_plus(); // zoom+-
    void scale_minus();
    void rotate_up(); // методы поворотов
    void rotate_down();
    void rotate_left();
    void rotate_right();
    void translate_down();
    void translate_up();
    void defaultScene(); //сцена поумолчанию

    void drawAxis(); //построить оси координат

    void getVertexArray(int,GLfloat**); // определить массив вершин
    void getColorArray();  // определить массив цветов
    void drawGraf(); // построить фигуру
protected:
    void initializeGL();
    void resizeGL(int nWidth, int nHeight);
    void paintGL();

    void mousePressEvent(QMouseEvent * pe);
    void mouseMoveEvent(QMouseEvent *pe);
    void keyPressEvent(QKeyEvent * pe);

};

#endif // SCENE3D_H

graf3d.cpp:


#include <QtGui>
#include <math.h>
#include "graf3d.h"

const static float pi=3.141593, k=pi/180;

graf3d::graf3d(QWidget *parent)
    : QGLWidget(parent)
{
    xRot=-90;
    yRot=0;
    zRot=0;
    zTra=0;
    nSca=1;
}

graf3d::~graf3d()
{

}

void graf3d::set_param(int gnum,int n)
{
    ng=gnum;
    nv=n;
    VertexArray=new GLfloat**[ng];
    ColorArray=new GLfloat*[ng];
    for(int i=0;i<ng;i++)
    {
        VertexArray[i]=new GLfloat*[nv];
        ColorArray[i]=new GLfloat[3];
        for(int j=0;j<nv;j++)
            VertexArray[i][j]=new GLfloat[3];

    }
}

void graf3d::initializeGL()
{
    qglColor(Qt::black);
    glEnable(GL_DEPTH_TEST); // устанавливаем режим проверки глубины пикселя
    glShadeModel(GL_FLAT);
    glEnable(GL_CULL_FACE);
}

void graf3d::resizeGL(int nWidth, int nHeight)
{
    glMatrixMode(GL_PROJECTION); //устанавливаем текущую проекционную матрицу
    glLoadIdentity();

    GLfloat ratio=nHeight/nWidth;

    if(nWidth>=nHeight)
        glOrtho(0.1/ratio, 1.0/ratio, -1.0, 1.0, -10.0, 1.0); //параметры
        //видимости ортоганальной проекции

        //!!!!!!!!!
    glViewport(0,0,(GLint)nWidth,(GLint)nHeight);



}

void graf3d::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

//    последовательно преобразование
    glScalef(nSca,nSca,nSca); // масштабирование
    glTranslatef(0.0f, zTra,0.0f);
    glRotatef(xRot,1.0f,0.0f,0.0);
    glRotatef(yRot,0.0f,1.0f,0.0);
    glRotatef(zRot,0.0f,0.0f,1.0);

    drawAxis();
//    drawGraf();  //РАСКАМЕНТИТЬ ЧТО БЫ ВЫВОДИТЬ ГРАФИКИ
}

void graf3d::mousePressEvent(QMouseEvent *pe)
{
    ptrMousePosition=pe->pos();
}

void graf3d::mouseMoveEvent(QMouseEvent *pe)
{
    xRot+=180/nSca*(GLfloat)(pe->y()-ptrMousePosition.y())/height();
    zRot+=180/nSca*(GLfloat)(pe->x()-ptrMousePosition.x())/width();

    ptrMousePosition=pe->pos();

    updateGL();
}

void graf3d::keyPressEvent(QKeyEvent* pe) // нажатие определенной клавиши
{
   switch (pe->key())
   {
      case Qt::Key_Plus:
         scale_plus();     // приблизить сцену
      break;

      case Qt::Key_Equal:
         scale_plus();     // приблизить сцену
      break;

      case Qt::Key_Minus:
         scale_minus();    // удалиться от сцены
      break;

      case Qt::Key_Up:
         rotate_up();      // повернуть сцену вверх
      break;

      case Qt::Key_Down:
         rotate_down();    // повернуть сцену вниз
      break;

      case Qt::Key_Left:
        rotate_left();     // повернуть сцену влево
      break;

      case Qt::Key_Right:
         rotate_right();   // повернуть сцену вправо
      break;

      case Qt::Key_Z:
         translate_down(); // транслировать сцену вниз
      break;

      case Qt::Key_X:
         translate_up();   // транслировать сцену вверх
      break;

      case Qt::Key_Space:  // клавиша пробела
         defaultScene();   // возвращение значений по умолчанию
      break;

      case Qt::Key_Escape: // клавиша "эскейп"
         this->close();    // завершает приложение
      break;
   }

   updateGL(); // обновление изображения
}

void graf3d::scale_plus() // приблизить сцену
{
   nSca = nSca*1.1;
}

void graf3d::scale_minus() // удалиться от сцены
{
   nSca = nSca/1.1;
}

void graf3d::rotate_up() // повернуть сцену вверх
{
   xRot += 1.0;
}

void graf3d::rotate_down() // повернуть сцену вниз
{
   xRot -= 1.0;
}

void graf3d::rotate_left() // повернуть сцену влево
{
   zRot += 1.0;
}

void graf3d::rotate_right() // повернуть сцену вправо
{
   zRot -= 1.0;
}

void graf3d::translate_down() // транслировать сцену вниз
{
   zTra -= 0.05;
}

void graf3d::translate_up() // транслировать сцену вверх
{
   zTra += 0.05;
}

void graf3d::defaultScene() // наблюдение сцены по умолчанию
{
   xRot=-90; yRot=0; zRot=0; zTra=0; nSca=1;
}

void graf3d::drawAxis()
{
    glLineWidth(3.0f);

    glBegin(GL_LINES); // построение линии
        glVertex3f( 1.0f,  0.0f,  0.0f); // первая точка
       glVertex3f(-1.0f,  0.0f,  0.0f); // вторая точка
    glEnd();

    QColor halfGreen(0, 128, 0, 255);
    qglColor(halfGreen);
    glBegin(GL_LINES);
       // ось y зеленого цвета
       glVertex3f( 0.0f,  1.0f,  0.0f);
       glVertex3f( 0.0f, -1.0f,  0.0f);

       glColor4f(0.00f, 0.00f, 1.00f, 1.0f);
       // ось z синего цвета
       glVertex3f( 0.0f,  0.0f,  1.0f);
       glVertex3f( 0.0f,  0.0f, -1.0f);
    glEnd();
}


void graf3d::getVertexArray(int gpos,GLfloat **array) // определить массив вершин
{
    for(int i=0;i<nv;i++)
        for(int j=0;j<3;j++)
            VertexArray[gpos][i][j]=array[i][j];
}

void graf3d::getColorArray() // определить массив цветов вершин
{
   for (int i=0; i<ng; i++)
   {
      ColorArray[i][0]=0.1f;//*(qrand()%11); // R - красная составляющая
      ColorArray[i][1]=0.1f;//*(qrand()%11); // G - зелёная составляющая
      ColorArray[i][2]=0.1f;//*(qrand()%11); // B - синяя составляющая
   }
}


void graf3d::drawGraf() // построить фигуру
{
    glLineWidth(3.0f);

    for(int i=0;i<ng;i++)
    {
        QColor tmp(0, 128, 0, 255);
        for(int j=0;j<nv-1;j++)
        {
        glBegin(GL_LINES); // построение линии
            glVertex3f(VertexArray[i][j][0],  VertexArray[i][j][1],  VertexArray[i][j][2]); // первая точка
            glVertex3f(VertexArray[i][j+1][0],  VertexArray[i][j+1][1],  VertexArray[i][j+1][2]); // вторая точка
        glEnd();
        }
    }
}

Но если создать отдельный проект, и указать что класс graf3d является основным то при компиляции появляется окно и все вроде бы работает.

зы: я начинающий в этом нелегком деле, поэтому не судите строго

★★★

graf3d graf;

graf.show();

Вряд ли ошибусь, если скажу, что где-то очень скоро после этого происходит завершение функции и все стековые объекты прибиваются.

АМ.

ram
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.