With the following simple test code, I can observe behavior that is not consistent with what the API documentation led me to believe:
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
void getTimestamp(char buf[32]) {
time_t rawNow;
time(&rawNow);
struct tm localNow;
localtime_s(&localNow, &rawNow);
strftime(buf, 32, "%c", &localNow);
}
void window_size_callback(GLFWwindow *window, int callbackwidth, int callbackheight) {
char timestamp[32];
getTimestamp(timestamp);
int width, height;
glfwGetWindowSize(window, &width, &height);
if (printf("%s\nWindow size as reported to callback function: %dx%d\nWindow size according to glfwGetWindowSize: %dx%d\n\n", timestamp, callbackwidth, callbackheight, width, height) < 0)
perror("printf");
}
void framebuffer_size_callback(GLFWwindow *window, int callbackwidth, int callbackheight) {
char timestamp[32];
getTimestamp(timestamp);
int width, height;
glfwGetFramebufferSize(window, &width, &height);
if (printf("%s\nFrame buffer size as reported to callback function: %dx%d\nFrame buffer size according to glfwGetFramebufferSize: %dx%d\n\n", timestamp, callbackwidth, callbackheight, width, height) < 0)
perror("printf");
}
int main() {
if (!glfwInit()) {
if (fprintf(stderr, "Failed to initialize GLFW.\n") < 0)
perror("fprintf");
exit(EXIT_FAILURE);
}
GLFWmonitor *primarymonitor = glfwGetPrimaryMonitor();
const GLFWvidmode *videomode = glfwGetVideoMode(primarymonitor);
glfwWindowHint(GLFW_RED_BITS, videomode->redBits);
glfwWindowHint(GLFW_GREEN_BITS, videomode->greenBits);
glfwWindowHint(GLFW_BLUE_BITS, videomode->blueBits);
glfwWindowHint(GLFW_REFRESH_RATE, videomode->refreshRate);
GLFWwindow *window = glfwCreateWindow(videomode->width, videomode->height, "Test", primarymonitor, NULL);
if (!window) {
if (fprintf(stderr, "Failed to open GLFW window.") < 0)
perror("fprintf");
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetWindowSizeCallback(window, window_size_callback);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
{
char timestamp[32];
getTimestamp(timestamp);
int wwidth, wheight;
glfwGetWindowSize(window, &wwidth, &wheight);
int fbwidth, fbheight;
glfwGetFramebufferSize(window, &fbwidth, &fbheight);
if (printf("Started test at %s\nInitial window size: %dx%d\nInitial frame buffer size: %dx%d\n\n", timestamp, wwidth, wheight, fbwidth, fbheight) < 0)
perror("printf");
}
do {
glfwPollEvents();
} while (!glfwWindowShouldClose(window));
}
My experiment is to start the program in Windows 7, go to the Control Panel and change the primary monitor from landscape to portrait, and then restore focus to the test program. Here is what I get:
Started test at 04/17/16 10:57:26
Initial window size: 1920x1200
Initial frame buffer size: 1920x1200
04/17/16 10:57:43
Frame buffer size as reported to callback function: 0x0
Frame buffer size according to glfwGetFramebufferSize: 0x0
04/17/16 10:57:43
Window size as reported to callback function: 0x0
Window size according to glfwGetWindowSize: 0x0
04/17/16 10:58:03
Frame buffer size as reported to callback function: 1200x1920
Frame buffer size according to glfwGetFramebufferSize: 1200x1920
04/17/16 10:58:03
Window size as reported to callback function: 1200x1920
Window size according to glfwGetWindowSize: 1200x1920
04/17/16 10:58:03
Frame buffer size as reported to callback function: 1920x1200
Frame buffer size according to glfwGetFramebufferSize: 1200x1920
04/17/16 10:58:03
Window size as reported to callback function: 1920x1200
Window size according to glfwGetWindowSize: 1200x1920
So you see, restoring focus to the test program results in two calls to each of the two callback functions: one to go back from 0x0 to 1920x1200, and another to change to 1200x1920. Unfortunately, the one that reports 1200x1920 comes first, followed by 1920x1200. There must be something wrong; if nothing else, the API documentation is misleading where it gives this example frame buffer callback function:
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
The above function does not work. Here is my attempt at it:
void framebuffer_size_callback(GLFWwindow* window, int eventwidth, int eventheight)
{
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
}
A window size callback has to be written with the same consideration in mind, that calls may happen in no particular order.