I was doing some tests with the timer, it is quite accurate, although with approximately 11 ms is 98% accurate most of the time, I created two timers, each with a counter, one average every 1 second, and the other every 11 ms, the one with 11 ms gave between 89 to 91 in the counter for each second most of the time, but if I put it at 1 ms it gave me 50% of the total needed, that is, instead of giving me 1000 which would be 1 second, it gave me 450 or 560, or 720, in fact it gave me the amount of fps on screen, this with version 1. 8.5, then I thought I would have 1 ms of sleep something in the code, remembering again and reading your comment I confirm it, but instead of using 0 in sleep, how about changing from milliseconds to microseconds? in the standard library it would be something like std::this_thread::sleep_for(std::chrono::microseconds(100));, which is 0.1 ms, instead of std::this_thread::sleep_for(std::chrono::milliseconds(1)); which is 1 ms.CuteAlien wrote: ↑Mon Mar 18, 2024 10:57 am @Noiecity: Yeah - it's about Windows timer in general which are used for example in Windows sleep(). Irrlicht uses those for it's device->sleep(). Which I don't recommend using anymore therefore. Up to (including) Irrlicht 1.8 we also used sleep(1) for device->yield(), so that was just as bad. But that is now using sleep(0) in Irrlicht svn trunk (aka Irrlicht 1.9), so that can be used again as it now only gives up the thread (reason it used sleep(1) in the past was some Windows 98 behavior where using sleep(0) wasn't guarenteed to give up threads, but Microsoft changed that behavior afterwards).
@n00bc0de: Are you on Irrlicht 1.8 or svn trunk? Could be something changed. Also if you show me your main-loop I might have more ideas.
I want to use svn now, but it would be great to be able to configure the sleep inside the project somehow, although maybe it's already there, I don't know.
Also maybe the sleep time should vary between what is rendered and what is calculated metrically, the only way I have thought of is with two loops, some time ago I programmed a game in java where something like this was executed: the server executed all the mathematical logic and was assigned an amount of ram memory, while another application was in charge of rendering, so that if the animations were lagged or an error occurred, the server was not affected and the character returned to the place where it should be, because it was only the visible part.
Nowadays it is normal to see in other engines characters crossing the floor and falling infinitely because of these errors in the memory that cause problems in collisions, even with a real engine, it could be corrected by normalizing every certain amount of time also based on some conditions, as the movement is limited to the coordinates of a mesh, instead of calculating using a timer that collides one mesh with another, in an error, the mesh could move beyond what is allowed. This happened to me in irrlicht by the way, in some tests with very low FPS, this really could happen, characters going through the collisions, although it was rare, but it happened, although it was more because of how I had programmed it, something like "move every 15 ms" and when it lagged 15 ms turned out to be seconds and the condition was skipped, I spent about two days without understanding why it happened, if literally in the if I placed that the movement was not executed if the calculated movement added gave more than the specified limit, I do not have the code but I remember that it was like that, it was probably my mistake, I do not know.
At the moment I have thought of some solutions in case of an extreme lag out of the blue, for example, if irrlicht is currently giving me with a deltatime of 1 ms half, it can be fixed by normalizing every 10 ms, if in 10 ms the counter gives me 5, it means that I can normalize by multiplying the 1 ms*2, of course, this normalization would have to be updated according to the average performance of the application in case of a discontinuous performance.
At the moment I can't use 1 ms if I have less than 1000 fps, but, probably in svn I can.
Code: Select all
#include <iostream>
#include <irrlicht.h>
#include <Windows.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
int main() {
IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9, core::dimension2d<u32>(800, 600), 32, false, false, false, 0);
if (!device) {
std::cerr << "Error" << std::endl;
return 1;
}
u32 lastTime = device->getTimer()->getTime();
u32 lastTime2 = device->getTimer()->getTime();
u32 count = 0;
u32 count2 = 0;
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
smgr->addCameraSceneNode(0, vector3df(0, 30, -40), vector3df(0, 5, 0));
bool disableTime = false; //for later
while (device->run())
{
u32 currentTime = device->getTimer()->getTime();
u32 currentTime2 = device->getTimer()->getTime();
u32 elapsedTime = currentTime - lastTime;
u32 elapsedTime2 = currentTime2 - lastTime2;
if (elapsedTime >= 1 && disableTime==false) {
count++;
lastTime = currentTime;
}
if (elapsedTime2 >= 1000 && disableTime==false) {
count2++;
std::cout << "count1: " << count << std::endl;
std::cout << "count2: " << count2 << std::endl;
count = 0;
count2 = 0;
lastTime2 = currentTime2;
}
//driver->beginScene(true, true, SColor(255, 100, 101, 140));
//smgr->drawAll();
//guienv->drawAll();
//driver->endScene();
}
device->drop();
return 0;
}