Russian Qt Forum
Ноябрь 23, 2024, 00:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Игра Танки. Segmentation error  (Прочитано 12552 раз)
8Observer8
Гость
« : Январь 12, 2015, 23:11 »

Привет

Не могу понять почему происходит ошибка. Запустите, пожалуйста, программу и нажмите "пробел": https://github.com/8Observer8/Tanks

Код
C++ (Qt)
void ExplosionOfProjectile::genTextures()
{
   QImage image( ":/Texture/TankSpriteSheet.png" );
   image = image.mirrored( false, true );
 
   QImage frame;
 
   frame = image.copy( 257, 112, 15, 15 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
   frame = image.copy( 272, 112, 16, 16 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
   frame = image.copy( 287, 111, 18, 18 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
}
« Последнее редактирование: Январь 13, 2015, 18:36 от 8Observer8 » Записан
8Observer8
Гость
« Ответ #1 : Январь 12, 2015, 23:32 »

Ошибка происходит на строке из кода выше:

Код
C++ (Qt)
m_textures.push_back( new QOpenGLTexture( frame ) );
Записан
8Observer8
Гость
« Ответ #2 : Январь 13, 2015, 10:34 »

Там такая ситуация: когда я нажимаю на пробел, выполняется секция case Qt::Key_Space в этой функции:

Код
C++ (Qt)
void Scene::keyPressEvent( QKeyEvent *event )

Запускается таймер m_projectileTimer.start( 20 );

Каждые 20 милисекунд вызывается функция: void Scene::slotOfMovingOfProjectiles()

Крэш происходит когда сняряд подлетает к стенке и должен взорваться. Это происходит, когда Y-координата снаряда меньше или равна нулю. Тогда вызывается функция: addProjectileExplosion( x0, y0 ); которой передаётся положение снаряда. Эта функция должна показать анимацию взрыва:

Код
C++ (Qt)
void Scene::addProjectileExplosion( float x0, float y0 )
{
   ExplosionOfProjectile *explosion = new ExplosionOfProjectile( &m_program, m_vertexAttr, m_textureAttr, m_textureUniform );
   explosion->setX0( x0 );
   explosion->setY0( y0 );
   connect( explosion, SIGNAL( signalShowProjectileExplosion( int, bool ) ),
            this, SLOT( slotShowProjectileExplosion( int, bool ) ) );
   m_projectileExplosions[explosion->id()] = explosion;
   explosion->start();
 
   update();
}

Ошибка происходит при создании объекта:  "ExplosionOfTank *explosion = new"

Точнее, на строке m_textures.push_back

Код
C++ (Qt)
void ExplosionOfProjectile::genTextures()
{
   QImage image( ":/Texture/TankSpriteSheet.png" );
   image = image.mirrored( false, true );
 
   QImage frame;
 
   frame = image.copy( 257, 112, 15, 15 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
   frame = image.copy( 272, 112, 16, 16 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
   frame = image.copy( 287, 111, 18, 18 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
}

Не могу понять в чём ошибка. Почему "segmentation error"?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Январь 13, 2015, 10:54 »

Для начала перед строкой вылета вставить
Код
C++ (Qt)
qDebug() << image << frame;

Потом открыть букварь и прочитать
Цитировать
This does create the underlying OpenGL texture object. Therefore, construction using this constructor does require a valid current OpenGL context.
И убедиться что контекст создан и установлен.
« Последнее редактирование: Январь 13, 2015, 10:58 от Igors » Записан
8Observer8
Гость
« Ответ #4 : Январь 13, 2015, 11:06 »

Добавил и получил:
Цитировать
QImage(null) QImage(null)

Сначала обрадовался, так как у видел, что пропустил букву "s" в слове Texture, исправил:

Код
C++ (Qt)
QImage image( ":/Textures/TankSpriteSheet.png" );

Теперь выводится:

Код
C++ (Qt)
QImage(QSize(400, 256),format=5,depth=32,devicePixelRatio=1,bytesPerLine=1600,byteCount=409600) QImage(QSize(15, 15),format=5,depth=32,devicePixelRatio=1,bytesPerLine=60,byteCount=900)

Самое обидное, что крэш так и истался на:

Код
C++ (Qt)
m_textures.push_back( new QOpenGLTexture( frame ) );
« Последнее редактирование: Январь 13, 2015, 11:09 от 8Observer8 » Записан
8Observer8
Гость
« Ответ #5 : Январь 13, 2015, 11:08 »

Потом открыть букварь и прочитать
Цитировать
This does create the underlying OpenGL texture object. Therefore, construction using this constructor does require a valid current OpenGL context.
И убедиться что контекст создан и установлен.

Вот это самое непонятное. Дело в том, что танк создаётся абсолютно также, как снаряд. Никакой разницы между классами. С танком прокатывает, а со снарядом нет. Так не должно быть
Записан
8Observer8
Гость
« Ответ #6 : Январь 13, 2015, 11:16 »

Единственная разница - объект класса Tank создаётся в initializeGL(), а объект класса ExplosionOfProjectile в слоте
Записан
8Observer8
Гость
« Ответ #7 : Январь 13, 2015, 11:19 »

Я добавил makeCurrent()\doneCurrent(), но всё равно не помогло:

Код
C++ (Qt)
void Scene::addProjectileExplosion( float x0, float y0 )
{
   makeCurrent();
   ExplosionOfProjectile *explosion = new ExplosionOfProjectile( &m_program, m_vertexAttr, m_textureAttr, m_textureUniform );
   explosion->setX0( x0 );
   explosion->setY0( y0 );
   connect( explosion, SIGNAL( signalShowProjectileExplosion( int, bool ) ),
            this, SLOT( slotShowProjectileExplosion( int, bool ) ) );
   m_projectileExplosions[explosion->id()] = explosion;
   explosion->start();
   doneCurrent();
 
   update();
}
Записан
8Observer8
Гость
« Ответ #8 : Январь 13, 2015, 11:32 »

Как передать контекст?
Записан
8Observer8
Гость
« Ответ #9 : Январь 13, 2015, 12:09 »

Ошибка не при создании объекта. Я ставлю точку останова на update() и программа останавливается, но потом если продолжить, то происходит крэш:

Код
C++ (Qt)
void Scene::addProjectileExplosion( float x0, float y0 )
{
   ExplosionOfProjectile *explosion = new ExplosionOfProjectile( &m_program, m_vertexAttr, m_textureAttr, m_textureUniform );
   explosion->setX0( x0 );
   explosion->setY0( y0 );
   connect( explosion, SIGNAL( signalShowProjectileExplosion( int, bool ) ),
            this, SLOT( slotShowProjectileExplosion( int, bool ) ) );
   m_projectileExplosions[explosion->id()] = explosion;
   explosion->start();
 
   update();
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Январь 13, 2015, 12:15 »

Выложите проект zip'ом, если соберется (Вындоуз, GL 3.3) - посмотрю
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #11 : Январь 13, 2015, 12:17 »

Не, ну вы же пишите статьи по "современным контейнерам", а тут недоумеваете:

Код
C++ (Qt)
   std::vector<QOpenGLTexture*> m_textures;
   ...
   frame = image.copy( 257, 112, 15, 15 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
   frame = image.copy( 272, 112, 16, 16 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
   frame = image.copy( 287, 111, 18, 18 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 

  
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
8Observer8
Гость
« Ответ #12 : Январь 13, 2015, 12:18 »

Выложите проект zip'ом, если соберется (Вындоуз, GL 3.3) - посмотрю
Вот здесь справа кнопка "Donwload ZIP"
Записан
8Observer8
Гость
« Ответ #13 : Январь 13, 2015, 12:19 »

Не, ну вы же пишите статьи по "современным контейнерам", а тут недоумеваете:

Код
C++ (Qt)
   std::vector<QOpenGLTexture*> m_textures;
   ...
   frame = image.copy( 257, 112, 15, 15 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
   frame = image.copy( 272, 112, 16, 16 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
   frame = image.copy( 287, 111, 18, 18 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 

Здесь всё нормально теперь. Там проблема была - ошибка в пути. Теперь этот момент проходит. Я выше написал
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #14 : Январь 13, 2015, 12:20 »

Цитировать
Здесь всё нормально теперь. Там проблема была - ошибка в пути. Теперь этот момент проходит. Я выше написал
Эх.. Ничего вы не поняли(
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.66 секунд. Запросов: 22.