I'm gonna cut straight to the chase; I'm writing in c++ and I'm using glew (openGL). A recurring problem however is that when I first open the window and clear it, the 'glClear' doesn't fill the window with white as expected. It starts with an offset from the top left corner. This offset happens to be the exact same offset as the distance between my window and the top left corner of my screen so I suspect something funky about that. However, I haven't found anything online about it for 3 hours, so I decided to ask the question myself. Attached is the code and a screenshot of the problem. Screen capture of the window here, the red lines are the same length and added after the screenshot.
#define GLEW_STATIC
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow* window;
int main(int argc, char **argv){
if(!glfwInit()) std::cout << "glfw failed to init" << std::endl;
window = glfwCreateWindow(400, 400, "firstWindow", NULL, NULL);
if(!window) std::cout << "window creation failed" << std::endl;
while (!glfwWindowShouldClose(window)){
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwMakeContextCurrent(window);
}
UPDATE:
I'm really new to the whole GL thing, I was told that glfwMakeContextCurrent should be called straight after glfwWindowCreate. Once i did this, the whole thing became less wrong. I now get a grey (NOT a white) background, partly atleast. However the problem persists. I cleared glew from the code since it wasn't used.
#include <iostream>
#include <GLFW/glfw3.h>
GLFWwindow* window;
int main(int argc, char **argv){
if(!glfwInit()) std::cout << "glfw failed to init" << std::endl;
window = glfwCreateWindow(400, 400, "firstWindow", NULL, NULL);
if(!window) std::cout << "window creation failed" << std::endl;
glfwMakeContextCurrent(window);
while (!glfwWindowShouldClose(window)){
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
}
Unlike some other windowing libraries GLFW doesn't leave the GL context it creates for you current after glfwCreateWindow() succeeds.
GL commands don't work too well without a current GL context so you should call glfwMakeContextCurrent() right after glfwCreateWindow(), not after you exit the event loop.
Right now I suspect you're just seeing leftover garbage pixels that the OS/driver didn't bother to clear out.
Also, seeing as you're using GLEW you're going to want to call glewInit() after glfwMakeContextCurrent() so all the GL function-pointers it declares aren't pointing off into nowhere.
As a quick hack, it resolves itself if you resize the window. Using the glfwSetWindowSize(window, width, height) fixes the problem, if the width or height is different from the windows current dimensions. I have no idea why. Again, this is a hack and IS NOT a solution.
#include <iostream>
#include <GLFW/glfw3.h>
GLFWwindow* window;
const int width = 400;
const int height = 400;
int main(int argc, char **argv){
if(!glfwInit()) std::cout << "glfw failed to init" << std::endl;
window = glfwCreateWindow(width, height-1, "firstWindow", NULL, NULL);
if(!window) std::cout << "window creation failed" << std::endl;
glfwMakeContextCurrent(window);
glfwSetWindowSize(window, width, height);
while (!glfwWindowShouldClose(window)){
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
}
Related
I'm trying to change the background color in a window generated by OpenGL/GLFW and I'm using a similar code than the one in the GLFW docs. I'm on Ubuntu 20.04 and the window background is always black, no matter the parameters in the glClearColor() function.
I tried this on Windows 10 using VS and it worked perfectly, but on Ubuntu it's not working at all. No error messages are generated.
I also followed The Cherno's Sparky game engine series, and tried encapsulating the glClear() function in a class method, but this didn't change anything.
This is the whole code:
#include <iostream>
#include <GL/gl.h>
#include <GLFW/glfw3.h>
int main(int argc, char *argv[])
{
std::cout << "Hello world!" << std::endl;
if (!glfwInit())
{
// Initialization failed
exit(EXIT_FAILURE);
}
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
if (!window)
{
// Window or OpenGL context creation failed
std::cout << "Error creating window!" << std::endl;
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
while (!glfwWindowShouldClose(window))
{
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
return 0;
}
I'm supposed to get a window with a red background but it's black.
As additional elements, I'm also using CMake to help configuring and building the project (quite overkill I know), and I believe clang is the compiler used for the project. Maybe that influences the result.
You need an appropriate loader after glfwMakeContextCurrent(window).
If you are using glad, you should call gladLoadGL(glfwGetProcAddress) after glfwMakeContextCurrent(window) as the official doc suggests here.
I have created a simple OpenGL program, following the LearnOpenGL tutorial. It just creates a window and fills it with a color. I am using Visual Studio 2019.
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
int main() {
// Initialize GLFW
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Create GLFW Window
GLFWwindow* window = glfwCreateWindow(800, 600, "Golden Retriever", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// Initialize GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// Render Loop
while (!glfwWindowShouldClose(window)) {
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
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);
}
The program works perfectly, however it uses way too much CPU (around 50%). Is it something in Visual Studio properties, or am i just doing something wrong in my code?
You can enable vsync with glfwSwapInterval(1)
The way Windows measures CPU time falls flat on its face for processes that spend most of their time blocking (=waiting) on kernel calls. What happens in your case is, that in order to V-Sync your program has to wait for the vertical retrace to happen. That usually involves waiting for a synchronization object that's locked from kernel context.d
In order to make Windows measure consumed CPU time accurately add a Sleep(1) right before the buffer swap call.
I'm doing my programming on MacOS 10.14.3 that has support for OpenGL 4.1.
I'm using glfw for the ui and glew for the extensions detection.
this is the my code so far:
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
const GLint WIDTH = 800, HEIGHT = 600;
int main() {
if (!glfwInit()) {
std::cout << "GLFW initialisation Failed";
glfwTerminate();
return 1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,1);
// Core profile = No Backwards Compatibility
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
// Allow forward compatibility
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,GL_TRUE);
GLFWwindow *mainWindow = glfwCreateWindow(WIDTH, HEIGHT, "Test Window", nullptr, nullptr);
if (!mainWindow) {
std::cout << "GLFW window creation Failed!";
glfwTerminate();
return 1;
}
// get buffer size information
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(mainWindow,&bufferWidth,&bufferHeight);
// Set context for GLEW to use
glfwMakeContextCurrent(mainWindow);
// Allow modern extension features
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::cout << "GLEW initialisation Failed!";
glfwDestroyWindow(mainWindow);
glfwTerminate();
return 1;
}
// Setup viewport size
glViewport(0,0,bufferWidth,bufferHeight);
while(!glfwWindowShouldClose(mainWindow)) {
// Get + handle user input events
glfwPollEvents();
// Clear window
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(mainWindow);
}
return 0;
}
this should be a basic started for an opengl application. it should init glfw and glew and paint the screen in red, and on top of that I can add my opengl drawing/rendering functions.
when I execute it instead of seeing a window with a red background color, the background color flickers between red and black.
any ideas why?
update
it appears that the screen flickers between black and red even if I choose a different color with glClearColor.
starting to think maybe glew isn't working properly.. i'll move back to glad and seee if there is any difference.
update 2
replaced glew with glad by removed glew code, generating glad code using the web interface, then included glad.h and added glad.c to compilation, and initialised glad with:
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
ok now that works properly... but I want to use glew... what may be the problem that's causing this ?
I have just started to learn about the OpenGL API using https://www.learnopengl.com/ and was using the code from the Hello Window tutorial to open a new GLFW window. However, something is not quite right as the console opens up immediately when executed but the window takes 2 seconds to open. Using the Visual Studio debugger I have found that glfwCreateWindow() seems to be the culprit but no information seems to exist on why it is slow for me.
The code goes as follows:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
void processInput(GLFWwindow* window);
void framebufferSizeCallback(GLFWwindow* window, int width, int height);
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Test", nullptr, nullptr); //This line takes 2 seconds to execute
if (window == nullptr)
{
std::cout << "Failed to instantiate GLFW window!" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialise GLAD" << std::endl;
return -1;
}
while (!glfwWindowShouldClose(window))
{
processInput(window);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
}
void framebufferSizeCallback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
I am using Visual Studio 2017 and have already tried running in debug and release mode as well as using different GLFW libs but to avail.
Nevermind, it turns out that I had set the preferred graphics processor in the NVIDIA Control Panel to be my GPU rather than auto-select which was causing the program to load in many OpenGL extensions using my GPU and therefore take longer to open the window. After changing the setting, the window opens in a much more reasonable time of 500 milliseconds by using the integrated graphics.
I have a small problem with glfw.
My code is really simple, I juste want to create an empty window.
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main(void) {
// initialise the windows
GLFWwindow *window;
if (!glfwInit()) {
return -1;
}
// create a windows
window = glfwCreateWindow(640, 480, "Test", NULL, NULL);
if (!window) {
fprintf(stderr, "Failed to initialize GLFW\n");
glfwTerminate();
return -1;
}
// make the window's current context
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// loop until the window close
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// swap back and front buffers
glfwSwapBuffers(window);
// poll the events
glfwPollEvents();
}
std::cout << "finished ";
glfwTerminate();
return 0;
}
This code compile but when I run it, I only have a white window. The title of the window is correct but everything inside is white...
I try to use glClearColor like that
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1, 1, 0, 0);
but my window still white....
I use visual studio 2015.
How to get a black window ?
Edit :
I forgot to add this:
glfwMakeContextCurrent(window);
For future visitors I'm posting the edit as a formal answer.
The thing missing here is to set the newly created window as the current OpenGL context by calling glfwMakeContextCurrent(window);
Interestingly the comments in the code say you are doing this
// make the window's current context
But then you do not call the method above but instead set the background colour immediately after. If you add the above method call after this comment and before you set the background colour then when I run your code it works fine.