Some questions about a first example of OpenGL

Hi all,

Please consider this example:


#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <std_lib_facilities_4.h>
using namespace std;

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow*);
int main() {
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	   // glfw window creation
	GLFWwindow* window = glfwCreateWindow(800, 600, "Hello OpenGL!", nullptr, nullptr);
	if (window == nullptr)
	{
		cout << "Failed to create GLFW window" << endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	   // glad: load all OpenGL function pointers
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		cout << "Failed to initialize GLAD" << endl;
		return -1;
	}

	glViewport(0, 0, 800, 600);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	while (!glfwWindowShouldClose(window))
	{
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		processInput(window);
		glfwSwapBuffers(window);

		  //check and call events
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}

//*******************************************

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
	glViewport(0, 0, width, height);
}

//******************************************

void processInput(GLFWwindow* window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);
}

1- Why do we need glfwPollEvents(); here? Apparently processInput(window); gets our Esc key when pressed.

2- This function:

void framebuffer_size_callback(GLFWwindow* window, int width, int height) 
           { ** *
               glViewport(0, 0, width, height); 
          }

is called by this statement: glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); Here the parameters width and height aren’t set, so how does the function above set its arguments to be used by glViewport?

Because glfwPollEvents is for more than just keyboard input.

The function is not called. All that this does is register a callback with GLFW. GLFW internals will call the function at an arbitrary later time, and will provide the missing arguments.

Because glfwPollEvents is for more than just keyboard input.

But I thought the key used here Esc is of processInput(window); to deal with not that glfwPollEvents! So while processInput(window); is for that key why do we still need glfwPollEvents, please?

GLFW internals will call the function at an arbitrary later time, and will provide the missing arguments.

So should always the function framebuffer_size_callback have this sort/kind of arguments and that body code so that it is suitable for GLFW to call later?

I saw this post a while ago. I was interested in answering your question, as I was curious about GLFW too. My initial reply is below. I wrote this before my complete reply I wrote in the blog post I linked below, so my initial reply shows more of my guesses. It did take me a long time to write the complete reply, but I did honestly want to say a lot about this. Hope it helps you and others.

===

From my experience with Windows API (I assume you’re running on Windows) and looking at a bit of the GLFW source, I think glfwPollEvents() is needed to call the necessary Windows API OS-specific functions involved with keeping active the event-driven system that allows for both communication between the Windows OS and a window on your screen.

Your processInput function calls glfwGetKey and glfwSetWindowShouldClose. These functions sound related to querying and setting data that are probably in C structs coded somewhere in GLFW source and not actually part of something like Windows API. The data in these structs though would have to have been updated by the event-driven system I mentioned earlier (I think message-driven is a good term too, as Windows API focuses on sending/receiving “messages”). This system is kept active by glfwPollEvents() on Windows. So what I think is happening is that the functionality in your processInput depends on glfwPollEvents. It wouldn’t work without it. Your program will actually crash if you try to comment it out. This suggests the importance of glfwPollEvents even more.

As mhagain mentioned, glfwSetFramebufferSizeCallback(window, framebuffer_size_callback) doesn’t call the framebuffer_size_callback function immediately. As noted in the GLFW docs, it’ll be called when the window is resized (the docs is also how you can tell how you’re supposed to define your callback like you do). More specifically, from the Windows API’s perspective, a window receives the WM_SIZE message after it is resized. There is data associated with it that involves the window’s new client height and width. This is likely passed on to your framebuffer_size_callback function and then to the glViewport function you defined in it.

Overall, the main idea I’m trying to point out is that, for Windows, you need glfwPollEvents() to keep the event-driven system between your window and the OS running. In other words, glfwPollEvents() is important for OS-specific functionality within GLFW. And your processInput functionality and glfwSetFramebufferSizeCallback function depend on what happens in glfwPollEvents().

A lot of this is just on my best guess. And I’m just writing this from the perspective of GLFW’s abstraction of the Windows API. Though I think the concept of an event-driven system is on other OS’s too.

Here’s a link to a blog post I made to my complete response on this. I want to say a lot about this, but I don’t want to unnecessarily flood this forum thread.

I highly recommend trying out Windows API if you’re on Windows and you’re curious about OS-specific functionality that comes from a function like glfwPollEvents. I felt like I got an amazing amount of insight on lower-level programming with something like this. And I think the API’s super cool too, from what I’ve done with it so far. It’s not easy to grasp at first, and it’s true that APIs today like Qt and GLFW are meant for making things done on Windows API faster and easier. But if you take the time to look into it, you’ll not only get more understanding of how a window management API like Windows API interacts with OpenGL, but you’ll get more worthwhile flexibility to develop apps beyond OpenGL, like DirectX, GDI, and also non-graphics related things. Not saying I’ve done big apps on all of those (I don’t know DirectX either), but from what I know so far just learning it, I can definitely say it’s powerful. I linked resources in the bottom of my blog post.