目前公司采用QT撰寫一個游戲界面
采用的是QOpenGLWidget實作
基本結構是:
2D界面部分采用多執行緒將各個部件先繪制到 QPixmap *上
最后采用一個單獨的執行緒疊加,在主執行緒PaintEvent中進行繪制
3D地形部分采用主執行緒的PaintGL實作,這其中繪制需要的資料由子執行緒提供,通過讀取檔案,拼接資料,抽取資料完成。
在測驗的時候發現:
1、在程式運行后,大約20分鐘出現段錯誤問題
2、如果切換地圖資料(從檔案再次讀取),也會出現段錯誤
問題都出現在 資料拼接部分
我做了測驗,先屏蔽3D繪制部分,結果一切正常。
現在我對3D繪制部分進行一個詳細的描述(代碼太多,不方便貼,等下貼關鍵部分的內容):
3D部分的流程:
1、程式啟動后,會啟動DataLoad子執行緒,該子執行緒為一直回圈作業的執行緒,直到程式結束。
2、在程式初始化程序,通過全域引數確定需要讀取的幾個資料檔案,并分別讀取到指標陣列 data0~data9
3、在初始化階段,將data0~data9按一定規則拼接為一個大的地形資料_DataNow
4、初始化完畢后,該回圈將從_DataNow中每秒讀取10次資料,并提供給外部介面繪制
5、如發生地圖切換事件,則重復2~3的步驟(期間終止第4步的回圈)
資料量: data0~data9的資料量為 short int [4800*6000], _DataNow的資料量為short int [14400*18000]
對外輸出的資料量目前為 float [20*20*3]
現將整個地形資料類的代碼貼出來,請大家幫我分析下如何解決上述的段錯誤問題:
DemPreLoad.h 頭檔案:
#ifndef DEMPRELOAD_H
#define DEMPRELOAD_H
#include <QString>
#include <QDebug>
#include <QFile>
#include <QThread>
#include "globalvariable.h"
class DemPreLoad : public QThread
{
public:
Q_OBJECT
public:
float* _points; //頂點陣列
int * _indices;//繪制序號
float* _colors;//頂點顏色
int _numIndices;//索引個數
float _latitude = 0.0f; //當前維度
float _longitude = 0.0f; //當前經度
int _radius = 0;
DemPreLoad();
void flushDem(float latitude, float longitude, int radius);//重繪函式,用于實時計算所需要dem的資料,生成頂點陣列、繪制序號、頂點顏色
~DemPreLoad()
{
requestInterruption();
quit();
wait();
}//解構式
private slots:
void run();
private:
QString* _Filenames; //檔案名字串陣列
int16_t* _Data0; //左上角資料塊
int16_t* _Data1; //中上資料塊
int16_t* _Data2; //右上資料塊
int16_t* _Data3; //左資料塊
int16_t* _Data4; //中資料塊(當前資料塊)
int16_t* _Data5; //右資料塊
int16_t* _Data6; //左下資料塊
int16_t* _Data7; //下資料塊
int16_t* _Data8; //右下資料塊
int16_t* _DataNow; // 整個資料塊(將前面9個資料塊進行連接)
demMeta* _FileHeader;//頭檔案資訊結構陣列
demMeta _FileHeaderNow; //頭檔案資訊結構陣列全部整合后的資料結構,對應_FileHeader
QString* GetFileName(float latitude, float longitude); //獲取當前經緯度所在的地圖資料檔案名(字串)
demMeta* GetDemFileHeader(QString directory,QString* filenames); //根據檔案名字串字串獲取地圖頭檔案資訊(陣列)
struct demMeta loadHeader(QString directory, QString filename);//根據檔案名字串字串獲取地圖頭檔案資訊
int16_t* LoadDemData( demMeta meta, QString filename, QString Directory);//讀取單個檔案資料到記憶體
int16_t* MixDataNow(int16_t* data0, int16_t* data1, int16_t* data2, int16_t* data3, int16_t* data4, int16_t* data5, int16_t* data6, int16_t* data7, int16_t* data8);//組合9個資料記憶體塊
demMeta MixHeaderNow(demMeta* FileHeaders);//組合9個頭檔案資訊
int16_t* LoadDemData_Area();//讀取當前經緯度視覺范圍所需要的高程資料
float * CaculatePoint(int16_t* data); //計算頂點坐標
int * CaculateIndeces(int16_t* data); //計算頂點索引
float * CaculateColors(int16_t* data); //計算頂點顏色
Location getLocation();//獲取當前經緯度在整個組合后的資料記憶體塊中所處的位置(col,row,index)
void DemInitlize(QString Directory, float latitude, float longitude); //dem資料初始化程序
};
#endif // DEMPRELOAD_H
dempreload.cpp檔案
#include "dempreload.h"
void DemPreLoad::run()
{
qDebug()<<":DemLoad from thread slot:" <<QThread::currentThreadId()<<endl;
float latchange,lonchange;
_LastLat=0;
_LastLon=0;
bool isUDPConnected=false;
bool isDeminit=false;
bool isdem_needUpdate=false;
ms_mutex.lock();
BSX_int dem_radius=mstatus->DEM_Radius;
ms_mutex.unlock();
while (!isInterruptionRequested())
{
ms_mutex.lock();
if (mstatus->UDP_Connect==1)
{
isUDPConnected=true;
}else isUDPConnected=false;
if (mstatus->DEM_init==1)
{
isDeminit=true;
}else isDeminit=false;
if (mstatus->DEM_needUpdate==1)
{
isdem_needUpdate=true;
}else isdem_needUpdate=false;
ms_mutex.unlock();
if (isUDPConnected)
{
if (pCurrentData->latitude!=0)
{
float lat=pCurrentData->latitude;
float lon=pCurrentData->longitude;
latchange=qAbs(lat-_LastLat);
lonchange=qAbs(lon-_LastLon);
if ((latchange>40)||(lonchange>40))
{
//qDebug()<<"latchange:"<<latchange<<" lonchange:"<<lonchange;
//qDebug()<<"plat:"<<pCurrentData->latitude<<" plon:"<<pCurrentData->longitude;
ms_mutex.lock();
mstatus->DEM_needUpdate=1;
isdem_needUpdate=true;
ms_mutex.unlock();
}else isdem_needUpdate=false;
if ((!isDeminit)||(isdem_needUpdate))
{
DemInitlize(_DEM_DIRECTORY, pCurrentData->latitude, pCurrentData->longitude);
ms_mutex.lock();
mstatus->DEM_init=1;
mstatus->DEM_needUpdate=0;
ms_mutex.unlock();
}else
{
flushDem(pCurrentData->latitude, pCurrentData->longitude,dem_radius);
}
_LastLat=lat;
_LastLon=lon;
}
}
msleep(100);
}
}
void DemPreLoad::DemInitlize(QString Directory, float latitude, float longitude)
{
_Filenames = GetFileName(latitude, longitude);
_FileHeader = GetDemFileHeader(Directory,_Filenames);
_Data0=new int16_t;
_Data1=new int16_t;
_Data2=new int16_t;
_Data3=new int16_t;
_Data4=new int16_t;
_Data5=new int16_t;
_Data6=new int16_t;
_Data7=new int16_t;
_Data8=new int16_t;
_Data0 = LoadDemData(_FileHeader[0], _Filenames[0], Directory);
_Data1 = LoadDemData(_FileHeader[1], _Filenames[1], Directory);
_Data2 = LoadDemData(_FileHeader[2], _Filenames[2], Directory);
_Data3 = LoadDemData(_FileHeader[3], _Filenames[3], Directory);
_Data4 = LoadDemData(_FileHeader[4], _Filenames[4], Directory);
_Data5 = LoadDemData(_FileHeader[5], _Filenames[5], Directory);
_Data6 = LoadDemData(_FileHeader[6], _Filenames[6], Directory);
_Data7 = LoadDemData(_FileHeader[7], _Filenames[7], Directory);
_Data8 = LoadDemData(_FileHeader[8], _Filenames[8], Directory);
_FileHeaderNow = MixHeaderNow(_FileHead
dem_mutex.lock();
_DataNow=MixDataNow(_Data0, _Data1, _Data2, _Data3, _Data4, _Data5, _Data6, _Data7, _Data8);
dem_mutex.unlock();
delete _Data0;
delete _Data1;
delete _Data2;
delete _Data3;
delete _Data4;
delete _Data5;
delete _Data6;
delete _Data7;
delete _Data8;
}
DemPreLoad::DemPreLoad()
{
_LastLat=0.0f;
_LastLon=0.0f;
_DataNow=new int16_t;
}
int16_t* DemPreLoad::MixDataNow(int16_t* data0, int16_t* data1, int16_t* data2, int16_t* data3, int16_t* data4, int16_t* data5, int16_t* data6, int16_t* data7, int16_t* data8)
{
int16_t * crop = (int16_t *)malloc(sizeof(int16_t)*14400*18000);
for (int rows = 0; rows < 18000; rows++)
{
if (rows < 6000)
{
for (int fl = 0; fl < 14400; fl++)
{
if (fl < 4800)
{
crop[rows * 14400 + fl] = data0[rows * 4800+fl]; //段錯誤問題出現在這里
}
else if (fl < 9600)
{
crop[rows * 14400 + fl] = data1[rows * 4800+fl - 4800];
}
else
{
crop[rows * 14400 + fl] = data2[rows * 4800+fl - 9600];
}
}
}
else if (rows < 12000)
{
for (int sl = 0; sl < 14400; sl++)
{
if (sl < 4800)
{
crop[rows * 14400 + sl] = data3[(rows - 6000) * 4800+sl];
}
else if (sl < 9600)
{
crop[rows * 14400 + sl] = data4[(rows - 6000) * 4800 + sl - 4800];
}
else
{
crop[rows * 14400 + sl] = data5[(rows - 6000) * 4800 + sl - 9600];
}
}
}
else
{
for (int tl = 0; tl < 14400; tl++)
{
if (tl < 4800)
{
crop[rows * 14400 + tl] = data6[(rows - 12000) * 4800 + tl];
}
else if (tl < 9600)
{
crop[rows * 14400 + tl] = data7[(rows - 12000) * 4800 + tl - 4800];
}
else
{
crop[rows * 14400 + tl] = data8[(rows - 12000) * 4800 + tl - 9600];
}
}
}
}
return crop;
}
int16_t* DemPreLoad::LoadDemData(demMeta meta, QString filename,QString Directory)
{
QString forFile = QString("%1gt30%2.dem").arg(Directory).arg(filename);
QFile infile(forFile);
int16_t* crop = (int16_t*)malloc(sizeof(int16_t) * meta.ncols * meta.nrows);
int16_t hight = 0;
int16_t low = 0;
int16_t result = 0;
if (!infile.open(QIODevice::ReadOnly))
{
int count=meta.ncols * meta.nrows;
for (int i = 0; i < count; i++)
{
crop[i] = 0;
}
qDebug() << "Cannot open file for reading: ";
return crop;
}
infile.seek(0);
for (int h = 0; h < meta.nrows; h++) {
for (int i = 0; i < meta.ncols; i++) {
infile.read((char*)&hight, 1);
infile.read((char*)&low, 1);
result = hight * 256 + low;
if (result == -9999)
{
result = 0;
}
crop[h*meta.ncols + i] = result;
}
}
infile.close();
return crop;
}
//由于篇幅問題,其他函式內容就不貼了,其他函式都作業正常。
錯誤: RtlWerpReportException failed with status code :-1073741823. Will try to launch the process directly
感謝各位大神指導。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/84483.html
標籤:Qt
