Войти
ПрограммированиеФорумГрафика

QT проблема отображения OpenGL

#0
13:41, 7 сен. 2011

Здравствуйте. Пытаюсь выводить OPenGL графику в QT приложении и получаю черный экран.

int main(int argc, char **argv)
{

  QApplication app(argc,argv);
  if(!QGLFormat::hasOpenGL())
  {
    cerr << "This system has no OpenGL support" << endl;
    return 1;
  }


  scene Scene;
  MainWindow mainWindow;
  mainWindow.setScene(&Scene);

  mainWindow.resize(800,800);
  mainWindow.show();




Vector3D<GLfloat> Rotation(0.1,0.1,0.0);


Model3D Ico((char *)"ccc1.obj");
Ico.setRotationSpeed(Rotation);
Rotation.set(0.0,-10.0,0.0);
Scene.addObject(&Ico);
Light light(0.0,0.0,4.0,0.0,0.7,0.9);
Scene.setLight(light);
Scene.enableAA(true);

app.exec();

А вот класс MainWindow унаследованный от QGLWidget:

#include "MainWindow.h"
#include <iostream>

using namespace std;
MainWindow::MainWindow(QWidget *parent) : QGLWidget(parent)
{
  Scene=NULL;
setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
}
void MainWindow::setScene(scene *sScene)

{
setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
  Scene=sScene;
}

void MainWindow::initializeGL()
{

  GLfloat lightpos[]={1.0,1.0,-3.0,1.0};
  GLfloat lightcolor[]={1.0,1.0,1.0,1.0};
  GLfloat lightamb[]={1.0,1.0,1.0,1.0};
  GLfloat mat_specular[] ={1.0,1.0,1.0,1.0};
  cout << "GL init start" << endl;
    glClearColor(0.0,0.0,0.0,1.0);
    glShadeModel(GL_SMOOTH);

    glEnable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_COLOR_MATERIAL);
    glDepthFunc(GL_LEQUAL);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialf(GL_FRONT,GL_SHININESS,128.0);
    glMaterialfv(GL_BACK,GL_SPECULAR,mat_specular);
    glMaterialf(GL_BACK,GL_SHININESS,128.0);


    glLightfv(GL_LIGHT0,GL_POSITION,lightpos);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,lightcolor);

    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_CULL_FACE);
    glEnable(GL_MULTISAMPLE);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    cout << "GL init end" << endl;

}

void MainWindow::resizeGL(int width, int height)
{
  glViewport(0,0,(GLsizei) width, (GLsizei)height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glFrustum(-1.0,1.0,-1.0,1.0,1.5,20000.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void MainWindow::paintGL()
{
  if (Scene!=NULL)
  {
Scene->processObjects();///функция поворачивает объекты и т.д.
Scene->Draw();///отрисовка всех объектов сцены
  }
}

что я делаю не так? Возможно мне необходимо поменять порядок вызова функций?


#1
13:54, 7 сен. 2011

Может glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) в PaintGL нужно добавить

#2
13:56, 7 сен. 2011
Может glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) в PaintGL нужно добавить

Оно есть в коде отрисовки сцены. И он вызывается и даже делает вид что отрисовывает, но экран так и остается черным.
#3
14:01, 7 сен. 2011

Если сделать вот так:

int main(int argc, char **argv)
{

Vector3D<GLfloat> Rotation(0.1,0.1,0.0);

scene Scene;



Model3D Ico((char *)"ccc1.obj");
Ico.setRotationSpeed(Rotation);

Rotation.set(0.0,-10.0,0.0);
Scene.addObject(&Ico);
Light light(0.0,0.0,4.0,0.0,0.7,0.9);
Scene.setLight(light);
Scene.enableAA(true);


QApplication app(argc,argv);
if(!QGLFormat::hasOpenGL())
{
  cerr << "This system has no OpenGL support" << endl;
  return 1;
}

MainWindow mainWindow;


mainWindow.setScene(&Scene);

mainWindow.resize(800,800);
mainWindow.show();


app.exec();

То сцена начинает отрисовываться, но без текстур.

#4
17:44, 7 сен. 2011

qmor
QT != Qt. QT = QuickTime.

#5
17:46, 7 сен. 2011

glEnable(GL_TEXTURE_2D);

#6
21:40, 7 сен. 2011
glEnable(GL_TEXTURE_2D);

это сделано. Более того весь код прекрасно работает под SDL
#7
7:48, 8 сен. 2011

    Метод QGLWidget::paintGL() вызывается лишь при вызове метода QGLWidget::update() или QGLWidget::repaint() (на самом деле QGLWidget::update() просто вызывает QGLWidget::repaint(), все эти методы унаследованы от QWidget). У тебя это всё вызывается пока только один раз - при показе окна (когда ты вызываешь QGLWidget::show()). Если будешь водить мышкой по окну или двигать самим окном, в общем, вызывать его постоянную перерисовку, то сцена начнёт рендериться. )
    Тебе нужно создать таймер и им вызывать обновление окна. Проще всего для этого воспользоваться таймером, уже входящим в QObject - в конструкторе просто вызываешь метод

startTimer(0);
    Метод унаследован от QObject, параметр - задержка между вызовами таймера в миллисекундах. 0 означает, что таймер будет вызываться так часто, как только сможет. У меня был случай, что при этом само окно тормозило (перемещение окна, изменение его размеров), хотя сам рендер шёл нормально. Баг был замечен на X11 и то лишь на одном компе, под Windows такого не было. Но в случае чего решается увеличением времени задержки до 1 - 10 миллисекунд.
    Далее тебе необходимо переопределить метод QObject::timerEvent(QTimerEvent*) и вызывать в нём QGLWidget::repaint() или QGLWidget::update():
void MainWindow::timerEvent(QTimerEvent*) {
    repaint();
}
    Ну и не забудь объявить метод MainWindow::timerEvent(QTimerEvent*) в соответствующем *.h-файле.

#8
8:21, 8 сен. 2011

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

QApplication app(argc,argv);
if(!QGLFormat::hasOpenGL())
{
  cerr << "This system has no OpenGL support" << endl;
  return 1;
}

MainWindow mainWindow;


mainWindow.setScene(&Scene);

mainWindow.resize(800,800);
mainWindow.show();


app.exec();
после загрузки сцены, то один раз она рендерится как раз таки по событию show(), но без текстур (насколько я понимаю надо сначала вызвать метод glinit(), чтобы glGenTextures мог работать). А вот если я провожу инициализацию до загрузки объектов, то что бы не делал получаю только черный экран, и попадаю в методы paingGL() если меняю размеры окна, и в нем происходит отрисовка, но экран так и остается пустым.
ПрограммированиеФорумГрафика

Тема в архиве.