How to calculate Frames per second in Qt Graphics Application - qt

I have an Qt based OpenGLES2.0 application, where I want to capture the FPS.
my application draw same geometry for 16 times and then try to know the FPS.
How can I make sure glDrawElements() has finished its job ?
I want to get the correct FPS.
Is there any way to make the glDrawElements()synchronous or Pooling the glDrawElements() complete?

define a Timer object in application window/widget class.
QTime frameTime;
Start the timer in initializeGL.
frameTime.start();
in PaintGL
paintGL ()
{
draw_your_geometry();
++frameCount;
if (frameTime.elapsed() >= 1000)
{
double fps = frameCount / ((double)frameTime.elapsed()/1000.0);
}
}

Related

QT: QGraphicsView not updating from inside loop

I'm trying to draw a picture to the screen repeatedly from inside an infinite loop. When I try to draw the picture to the QGraphicsView, it doesn't update unless I break from the loop. Here is my function with the infinite loop:
void MainWindow::displayNoise() {
QImage noise(WIDTH, HEIGHT, QImage::Format_RGB32);
float t = 0;
while (true) {
// Populate noise
rendered_image = noise;
DisplayQImage(rendered_image);
t += 0.200;
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
And here is DisplayQImage():
void MainWindow::DisplayQImage(QImage &i)
{
QPixmap pixmap(QPixmap::fromImage(i));
graphics_scene.addPixmap(pixmap);
graphics_scene.setSceneRect(pixmap.rect());
ui->scene_display->setScene(&graphics_scene);
}
Note that graphics_scene and rendered_image are members of MainWindow. If I insert a break statement after my call to DisplayQImage then the first frame renders, but if I don't exit the displayNoise function then the widget doesn't update. I set up a signal so that when I press N it calls displayNoise, and I know the loop is looping. Why isn't the picture showing?
It is because you are not giving the eventloop time to do it's thing. Your function is being called from the eventloop, and the rendering is called from the same eventloop, because they live in the same thread. So you have two options:
write your code in an asyncronous way, eg. with a QTimer.
manually call the eventloop: https://doc.qt.io/qt-5/qeventloop.html#processEvents
I think the first option is probably the nicest way.

How to continue after signal emission?

I'm building a Othello game in Qt quick and C++.
I use this code from QML dialog to start new game, when one player is human, I wait for input. When two players are PC, I face the problem that the GUI will wait for the slot to finish, in PC players the slot call flipTurn() (because it is PC, no input to wait for), flipTurn is recursive, so the GUI will block until the game end.
I want it to update the board after each move. link for the project:
reversi project
myBroker.createGame(blacktypebutton.checkedButton.playertype,
whitetypebutton.checkedButton.playertype,
getBlackAlgo(),
getWhiteAlgo(),
getBlackDep(),
getWhiteDep());
console.log("finished creating game !");
void Broker::flipTurn()
{
if(someoneWon()){
emit gameEnd();
return;
}
emit updateBoard();
if (currentGame->getTurn() == Constants::BLACK){
currentGame->setTurn(Constants::WHITE);
if (currentGame->getWhitePlayer().getType() == Constants::PC){
currentGame->pcMove(Constants::WHITE);
flipTurn();
}
else
currentGame->updatePossible();
}
else{
currentGame->setTurn(Constants::BLACK);
if (currentGame->getBlackPlayer().getType() == Constants::PC){
currentGame->pcMove(Constants::BLACK);
flipTurn();
}
else
currentGame->updatePossible();
return;
}
emit updateBoard();
}
bool Broker::createGame(int blacktype, int whitetype, int blackalg, int whitealg, int blackdep, int whitedep)
{
currentGame = new Game(blacktype,whitetype,blackalg,whitealg,blackdep,whitedep);
currentGame->setGameBoard(&gameBoard);
updatePossible();
emit gameStart();
}
void Broker::onGameStart()
{
if(currentGame->getTurnType() == Constants::PC){
currentGame->pcMove(currentGame->getTurn());
cout<<"in ongamestart slot"<<endl;
flipTurn();
}
}
Since it is a turn based game, you will just need a different source to trigger the next turn.
Instead of calling flipTurn() directly, you call it through Qt's event loop.
Since you probably will want the human in front of the computer to see the game progressing, very likely with a delay.
For example with a single shot timer
// instead of calling flipTurn() directly
QTimer::singleShot(500, this, SLOT(flipTurn()));
Call next flipTurn() after 500 milliseconds.
I used
QCoreApplication::processEvents();
After each call to flipTurn() , so the GUI engine process any waiting signals (in my case the updateBoard() signal).
Although it isn't the best solution, it worked well for my homework.

Basic PIC Programming issues

I am writing PIC code in C and encountered the following problems:
When I write my delay as _delay_ms(500), my code doesn't compile, it says it didn't recognize this instruction. I am using MPLAB.
I want to write a program that would count how many time the push button is pressed then return that value and display it using LED's. I know how to display it, but not how to make the program to wait for the push of the push button on the pickit.
main()
{
TRISA=0;//Sets all ports on A to be outputs
TRISB=1;//Sets all ports on B to be inputs
for(;;){
if(PORTBbits.RB0==1){//When the button is pressed the LED is off
PORTAbits.RA1 =0;
count=count+1;
}
else{
PORTAbits.RA1=1;
count = count +1;
}
if (count > 20){//if count =20 aka 20 button presses the LED turns on
PORTAbits.RA0=1;
}
else{
PORTAbits.RA0=0;
}
}
}
There are a few issues:
Assuming you're using a PIC24 or a dsPIC, you need to include libpic30.h
Before you include libpic30.h you need to #define FCY to be your instruction rate so that the delay takes the correct number of cycles. See the comments in the libpic30.h file for details.
The function is __delay_ms not _delay_ms. Note that there are two underscores at the beginning.
The name is all lower case, not Delay_ms as in your comment.
You need to add delay in your code when you detect a key is pressed. As you are saying the _delay_ms(500) is not recognized, You can try something like following:
unsigned char x;
// Just waste a few cycles to create delay
for (x = 0; x < 100; x++)
{
// No operation instruction
Nop();
}
You can create your own delay function with specific number of iterations of this for loop. Measure the exact delay created by this function using a profiler if you need. IMO any arbitrary delay, like say 100 iterations as stated above shall work.

contoling an interval in a linedit for ints

I have a lineEdit I use so the user can enter a frequency interval,
// Making the lineedit objects only accept numbers and align it leftside
ui->frequency->setValidator(new QIntValidator(36, 1000, this));
ui->frequency->setAlignment(Qt::AlignRight);
It works fine to the top limit 1000 but the lower dos not. So I created an slot to control it,
// Control freqeuncy interval
void gui::f_interval()
{
QString f = ui->frequency->text();
freq = f.toInt();
if (freq < 36)
{
int status = QMessageBox::warning(this,"Warning","Invalid frequency interval",QMessageBox::Ok);
}
}
and connected it to the signal of the lineEdit,
// Control frequency interval
connect(ui->frequency, SIGNAL(editingFinished()), this, SLOT(f_interval()));
so that when the user enters a number lower than 36 it gets a warning dialog window.
But it doesn't seem to work. can anyone help me?
You want to connect with textChanged signal instead of editingFinished.
LE: also i don't remember having issues with validator, so can you provide more details, like Qt version, Os version, compiler, maybe see if the issue is reproduced in a sample project.

QApplication constructor (Qt) takes up to 10 seconds

I have finished my first Qt application, and noticed that the QApplication constructor in the main.cpp files take up to 10 seconds to execute. This results in an annoying startup delay where I can't even show a splash screen.
When profiling this delay it turns out that the initializeMultitouch_sys method in the QApplicationPrivate class is the culprit. Specifically, the iInkTablets->get_Count(...) call takes all the time.
void QApplicationPrivate::initializeMultitouch_sys()
{
[...]
IInkTablets *iInkTablets = 0;
HRESULT hr = CoCreateInstance(QT_CLSID_InkTablets, NULL, CLSCTX_ALL, QT_IID_IInkTablets, (void**)&iInkTablets);
if (SUCCEEDED(hr)) {
long count = 0;
iInkTablets->get_Count(&count); // <== Takes 5-10 seconds!!
for (long i = 0; i < count; ++i) {
[...]
}
}
I am using Windows 7, but not utilizing any multi-touch feature. Any idea what causes this problem and how I can avoid it?
Thanks,
Fabian
UPDATE 2010-11-14 - PROBLEM SOLVED
I noticed that the problem then occured with all Qt based applications, including Qt Designer. A reboot fixed it.
This is fixed in 4.6.3 (QTBUG-6007/commit)

Resources