The GLFW window takes about 1 second to open is there anyway to shorten it?
std::cout << glfwGetTime() << '\n';
//glfwWindowHint(GLFW_DECORATED,0);//removes window borders for next created window
GLFWwindow * mainwindow = glfwCreateWindow(600,400,"FreemanGL",0,0);
std::cout << glfwGetTime();
First timer is less than 0.009 seconds, second is approx 1.05 seconds.
Related
I was developing an application with SDL and glad. I noticed that there were some small freezes in the animations. I have written a separate project with the minimal functionality and I found the issue appears even with a very basic setup.
This is the code:
#include <iostream>
#include <vector>
#include <fstream>
#include <SDL.h>
#include <glad/glad.h>
using namespace std;
// the application will close after this amount of time
const float MILISECONDS_TO_CLOSE = 10 * 1000;
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_Window* window =
SDL_CreateWindow(
"tracer",
100, 100,
800, 600,
SDL_WINDOW_OPENGL
);
SDL_GLContext context = SDL_GL_CreateContext(window);
// SDL_GL_SetSwapInterval(1); // this line mitigates the problem but just slightly
if (!gladLoadGL())
{
cout << "gladLoadGL failed" << endl;
}
const GLubyte *oglVersion = glGetString(GL_VERSION);
std::cout << "This system supports OpenGL Version: " << oglVersion << std::endl;
const GLubyte *gpuVendor = glGetString(GL_VENDOR);
std::cout << "Graphics card: " << gpuVendor << std::endl;
glClearColor(0.15f, 0.15f, 0.15f, 1.0f);
vector<unsigned> deltas;
deltas.reserve(10 * MILISECONDS_TO_CLOSE);
static unsigned firstTime, prevTime, curTime;
firstTime = prevTime = curTime = SDL_GetTicks();
while (true)
{
// compute delta time
curTime = SDL_GetTicks();
unsigned dt = curTime - prevTime;
prevTime = curTime;
deltas.push_back(dt);
// close the application after some time
if (curTime - firstTime > MILISECONDS_TO_CLOSE) break;
// handle closing events
SDL_Event event;
if (SDL_PollEvent(&event))
{
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE || event.type == SDL_QUIT) break;
}
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(window);
}
// save recorded deltas to a file
fstream f("out.txt", ios::out | ios::trunc);
for (unsigned dt : deltas) f << dt << endl;
f << flush;
f.close();
return 0;
}
The program records the time between frames during 10 seconds and saves the result in a text file.
I plotted the data using python I got this:
The horizontal axis tells the frame time in milliseconds. The vertical axis tells the time passed since the last frame. Also in milliseconds.
As you can see the time between frames is very irregular and there are periodic spikes (about 1 seconds between spikes).
I have uploaded the CMake project to a github repository, so you can test it if you wish.
I have tested with both my integrated and dedicated GPUs (Intel 530HD and NVIDIA GTX 960M).
The SDL version is 2.0.5.
I tested it on Windows 10 and Ubuntu 16.04 LTS.
EDIT:
I have ported the application to GLFW and the same happens. So, it is very unlikelly that there is a bug in SDL. I have updated the git repo accordingly, now there are two CMake projects.
EDIT2:
I have tested it in another computer and works fine.
I have no clue what's happening. Could it be a hardware problem? Then why it doesn't happen when I run other applications?
Driver problem? Very unlikelly because it happens both using the Intel and NVIDIA GPUs. Also, it happens on both Ubuntu and Windows.
I've had similar behavior (though with longer&lower plateaus, not spikes) caused by the CPU overheating and hence deciding to lower clock rate temporarily. If that happens with your PC, you can try to upgrade your internal coolers or add external ones. Or just lower the temperature setting on the air conditioner in your room.
Naturally, it was always more an issue during summer.
Here's where I've posted about it.
When I try to show an fps counter in my program with this code:
sf::Clock clock;
sf::Time time = clock.getElapsedTime();
std::cout << 1.0f / time.asSeconds() << std::endl;
clock.restart().asSeconds();
It just repeats the numbers "500000" and "333333", even though I set the framerate limit to 60. Any ideas on how to fix this?
I'm trying to make a simple tile-based platformer in C++ and SDL2. My framerate stays at 59-60 fps, but when I start to hold down a key, it loses about 10 fps. This happens even when I don't call update or retrieve the keystates. This is the code inside my game loop:
//keys = (Uint8 *)SDL_GetKeyboardState(NULL);
elapsed = SDL_GetTicks() - current;
current += elapsed;
timeSinceSecond += elapsed;
//update(keys, elapsed / 1000.0);
draw();
frames++;
if(timeSinceSecond >= 1000) {
timeSinceSecond = 0;
cout << frames << endl;
frames = 0;
}
next = SDL_GetTicks();
if(next - current < 1000.0 / framerate) {
SDL_Delay(1000.0 / framerate - (next - current));
}
Any ideas on why this is happening? Could it be that it's a problem with SDL2? I haven't tried this with SDL 1.2.
SDL_Delay will not work the way you want. It is not precise enough (has 10 millisecond precision), so it will be impossible to get required number of frames per second this way. Us vsync instead. Another thing is that printing to stderr/stdout is slow when console is visible. If you're printing something when key is pressed, or if pressing the key somehow increases amount of text being printed, game will slow down.
In my OpenGL program, in order to run it in fullscreen mode, I'm using the GLUT function glutGameModeString(const char *string). (where 'string' specifies the screen width,height,pixelDepth and refresh rate) To make it working in any system,i need to dynamically determine the screen width and screen height of the host system, prior to making the call to 'glutGameModeString' function.How do I do that?
I think you are wrong, there are the following constants:
GLUT_SCREEN_HEIGHT
GLUT_SCREEN_WIDTH
I've tested it, it works.
Just tested on Linux Mint 18
std::cout << "glut screen width(DEFUALT): " << GLUT_SCREEN_WIDTH << std::endl;
std::cout << "glut screen height(DEFAULT): " << GLUT_SCREEN_HEIGHT << std::endl;
std::cout << "glut screen width: " << glutGet(GLUT_SCREEN_WIDTH) << std::endl;
std::cout << "glut screen height: " << glutGet(GLUT_SCREEN_HEIGHT) << std::endl;
outputs:
glut screen width(DEFAULT): 200
glut screen height(DEFAULT): 201
glut screen width: 1366
glut screen height: 768
setting your window size to glutGet(GLUT_SCREEN_WIDTH/HEIGHT); will maximize your window, still has top bar and border.
Just calling glutFullScreen(); after initializing your window will make it full screen with no borders or anything, no need for the above stuff of getting your screen size.
I have a QMainWindow with:
Two widgets in a horizontal splitter. "m_liner" is on the right side
Both widgets have a minimum size of say, 300 pixels.
A checkbox to hide/show the right-side widget m_liner.
I want the overall QMainWindow to expand when showing the widget, and shrink when hiding. The code below does this except:
If both widgets are shown, the minimum window size is 600 pixels.
Shrink the window to this smallest size.
Uncheck the box to hide the right-side widget.
Program hides the right-side widget.
Program calls this->resize(300, height);
The window ends up being 600 pixels wide (the minimum size with both widgets visible), instead of around 300 (the minimum size with only the left widget).
Later, I can resize the window down to 300 pixels with the mouse or another button. But it won't resize to 300 in the checkbox event, even if I call resize several times.
Does anyone have an idea how to solve this?
Critical bit of code follows, I have a full project available if you need it:
void MainWindow::on_checkBox_stateChanged(int val)
{
std::cout << "-------------------- Checkbox clicked " << val << std::endl;
bool visible = val;
QWidget * m_liner = ui->textEdit_2;
QSplitter * m_splitter = ui->splitter;
int linerWidth = m_liner->width();
if (linerWidth <= 0) linerWidth = m_lastLinerWidth;
if (linerWidth <= 0) linerWidth = m_liner->sizeHint().width();
// Account for the splitter handle
linerWidth += m_splitter->handleWidth() - 4;
std::cout << "Frame width starts at " << this->width() << std::endl;
std::cout << "Right Panel width is " << m_liner->width() << std::endl;
// this->setUpdatesEnabled(false);
if (visible && !m_liner->isVisible())
{
// Expand the window to include the Right Panel
int w = this->width() + linerWidth;
m_liner->setVisible(true);
QList<int> sizes = m_splitter->sizes();
if (sizes[1] == 0)
{
sizes[1] = linerWidth;
m_splitter->setSizes(sizes);
}
this->resize(w, this->height());
}
else if (!visible && m_liner->isVisible())
{
// Shrink the window to exclude the Right Panel
int w = this->width() - linerWidth;
std::cout << "Shrinking to " << w << std::endl;
m_lastLinerWidth = m_liner->width();
m_liner->setVisible(false);
m_splitter->setStretchFactor(1, 0);
this->resize(w, this->height());
m_splitter->resize(w, this->height());
this->update();
this->resize(w, this->height());
}
else
{
// Toggle the visibility of the liner
m_liner->setVisible(visible);
}
this->setUpdatesEnabled(true);
std::cout << "Frame width of " << this->width() << std::endl;
}
Sounds to me like there are some internal Qt events that need to get propagated before it recognizes that you can resize the main window. If this is the case then I can think of two potential solutions:
Use a queued single shot timer to call the code that resizes your window down to 300px:
m_liner->hide();
QTimer::singleShot( 0, this, SLOT(resizeTo300px()) );
or, after you hide your widget you can try a call to processEvents() (this function has potentially dangerous side effects, so use with caution):
m_liner->hide();
QApplication::processEvents();
resize( w, height() );
Another potential solution would be to set the horizontal size policy of your widget to ignored when hiding it:
m_liner->hide();
m_liner->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred );
resize( w, height() );
When showing your widget again, you'd need to adjust the size policy again.