glClear() crashes GLFW when including GLAD - c++

When I started I used the GLFW example code:
#include <GLFW/glfw3.h>
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
When running this it gives me a black screen titled "Hello world" which is exactly what I want. But by simply adding GLAD:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
...and giving window hints:
//Specify the OpenGL versions we're using
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
Suddenly it tells me the window failed to initialize.
But by simply adding this:
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
...it allows the window to initialize but crashes when glClear(GL_COLOR_BUFFER_BIT) is called and it gives me the error
'./Voxel\ Game' terminated by signal SIGSEGV (Address boundary error)
I know this because when I remove that line it works, it just doesn't clear the screen.
This is the full code I have now in case the error is somewhere else in there:
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define SCREEN_WIDTH 640
#define SCREEN_HIEGHT 480
int main()
{
GLFWwindow* window;
//Initialize the library
if (!glfwInit())
{
std::cout << "Failed to initalize GLFW" << std::endl;
return -1;
}
//Specify the OpenGL versions we're using
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
//Create a windowed mode window and its OpenGL context
window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HIEGHT, "Voxel Game", NULL, NULL);
if (!window)
{
std::cout << "Failed create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
//Make the window's context current
glfwMakeContextCurrent(window);
//Loop until the user closes the window
while (!glfwWindowShouldClose(window))
{
//Render here
//glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//Swap front and back buffers
glfwSwapBuffers(window);
//Poll for and process events
glfwPollEvents();
}
glfwTerminate();
return 0;
}

You are not initializing glad, add gladLoadGL(glfwGetProcAddress); after glfwMakeContextCurrent() and check it returns OK.
In general, there is no OpenGL library apart from some old OpenGL1.1 stuff (in Windows at least), all those GL calls are implemented in the graphics drivers directly, GLAD library just defines a lot of function pointers and wraps them in nicer macros. Then during initialization, it will dynamically load the functions from the drivers present on the machine. Hence the need to generate GLAD for specific OpenGL version.
So if you get segfaults on some GL calls, a good guess is some of those functions were not found, maybe because they are not supported on the HW or because you did not setup GLAD/GLFW correctly.

Related

OpenGL empty project uses too much CPU

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.

openGL PBO use wglcontext, Not create window

My goal is get pixel data from main window. nothing any rendering.
like we see the monitor such as screencapture.
I tried to TRANSPARENT windows, glReadPixel.
so I have a TRANSPARENT windows and context.
glfwSetErrorCallback(errorCallback);
if (!glfwInit()) {
std::cerr << "Error: GLFW " << std::endl;
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_SAMPLES, 4);
const int Monitor_count = GetMonitors();
GLwindow = glfwCreateWindow(
nWidth, // width
nHeight, // height
"OpenGL_Test", // window title
NULL, NULL);
if (!GLwindow) {
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSwapInterval(1);
//glfwShowWindow(GLwindow);
if (glfwGetWindowAttrib(GLwindow, GLFW_TRANSPARENT_FRAMEBUFFER))
{
// ..
}
glfwSetWindowOpacity(GLwindow, 0.0f);
glfwMakeContextCurrent(GLwindow);
glfwSetKeyCallback(GLwindow, keyCallback);
glewExperimental = GL_TRUE;
GLenum errorCode = glewInit();
But I want get pixel data from GPU without create windows.
So I use wglcreatecontext Get mother window DC, HGLRC.
And When I set bind buffer, It gives runtime error.
if (!glfwInit()) {
std::cerr << "Error: GLFW" << std::endl;
exit(EXIT_FAILURE);
}
HDCC = GetDC(m_hWndCopy);
// HDC TDC = CreateCompatibleDC(HDCC);
HGLRC DC = wglCreateContext(HDCC);
GLuint pbo;
glGenBuffersARB(1, &pbo); <<Error Here
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pbo);
How can I solve problem?
Any idea or link?
From your question and comment replies I gather, that you want to use OpenGL to grab a screenshot of an arbitrary window? If so, then this is not what OpenGL is meant for. You cannot use OpenGL for taking screenshots reliably.
glReadPixels will work reliably only for things that you did draw with OpenGL in the first place!

glew32s.lib undfined reference

I use MinGW compiler and Code::Blocks IDE, 16.01.
I have interested in graphic library OpenGL. I've started to find articles and found one.
I've set up glew, freeglut and glfw by myself without using cMaker. Then, I've decided to link libraries into the project. So, I have the following sequence in Linker settings:
C:\MinGW\lib\glew\glew32s.lib
C:\MinGW\lib\freeglut\libfreeglut.a
C:\MinGW\lib\freeglut\libfreeglut_static.a
C:\MinGW\lib\glfw\libglfw3dll.a
C:\MinGW\lib\glfw\libglfw3.a
Following by this tutorial (in russian language) I've written in linker settings glew32s.lib (with 's'), 'cause it's a static library and I need this one. After that I've tried to compile but get these errors:
C:\MinGW\lib\glew\glew32s.lib(tmp\glew_static\Release\Win32\glew.obj):(.text$mn+0x7)||undefined reference to `_imp__wglGetProcAddress#4'|
C:\MinGW\lib\glew\glew32s.lib(tmp\glew_static\Release\Win32\glew.obj):(.text$mn+0x4)||undefined reference to `_imp__wglGetProcAddress#4'|
The code I've tried to compile is:
#include <iostream>
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;
// The MAIN function, from here we start the application and run the game loop
int main()
{
std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl;
// Init GLFW
glfwInit();
// Set all the required options for GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create a GLFWwindow object that we can use for GLFW's functions
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
if (window == nullptr)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Set the required callback functions
glfwSetKeyCallback(window, key_callback);
// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
glewExperimental = GL_TRUE;
// Initialize GLEW to setup the OpenGL Function pointers
if (glewInit() != GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
// Define the viewport dimensions
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
// Game loop
while (!glfwWindowShouldClose(window))
{
// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
glfwPollEvents();
// Render
// Clear the colorbuffer
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Swap the screen buffers
glfwSwapBuffers(window);
}
// Terminate GLFW, clearing any resources allocated by GLFW.
glfwTerminate();
return 0;
}
// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
std::cout << key << std::endl;
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
Then I wrote in linker settings glew32.lib (without 's'), comment glewExperimental = GL_TRUE; line and try again.
The program was compiled successfully. It was run and the result was as it must be.
But I want to use a static library instead of dynamic. How can it be solved?
I guess that library 'glew32s.lib' is built with Visual studio. So you cannot link with it unless you change your compiler.
I suggest you get a GLEW library built with MinGW or build one by yourself. Libraries for MinGW are named 'libNAME.a',
Also, dynamic libraries have no limitation on its name, so there could be no difference between static library (instead, they are named, like, libNAME_static.a or libNAMEs.a, ...)

Unusual output when trying to Create a blank window in open GL

I am trying to create a Blank Window in OpenGL with help of GLFW. below is my code
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <glfw3.h>
GLFWwindow* window;
#include <glm/glm.hpp>
using namespace glm;
int main( void )
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(800,600,"learnopengl",NULL,NULL);
if (window == NULL)
{
fprintf(stderr,"there is a problem with window creation\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
fprintf(stderr,"Failed to initialize GLEW\n");
return -1;
}
int width, height;
glfwGetFramebufferSize(window,&width,&height);
glViewport(0,0,width,height);
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
}
but when i try to run the above code instead of a black blank it shows an instance of my current screen in newly created window.
Why do you expect this code to result in a blank window?
As per the spec, the back buffer contents become undefined after you swap the buffers (and initially, they are of course undefined too). As a result, the output you should get is also undefined and basically anything might show up.
Add a glClear(GL_COLOR_BUFFER_BIT) to your render loop if you want some defined output.
I know the answer is late but may concern other people and help them, I ran this code and it's working pretty well, but the problem is not in your code, it is your video card driver, so what is happening ?
OpenGL has what is called "The Default Framebuffer", it is the Framebuffer (the buffer contains what you will see) that OpenGL is created with. It is created along with the OpenGL Context. Like Framebuffer Objects, the default framebuffer is a series of images. Unlike FBOs, one of these images usually represents what you actually see on some part of your screen. in other words the default framebuffer is the buffer used by the operating system to render your desktop and other application's windows, so your application is using the default framebuffer as the framebuffer is not edited by your app, so you may need to clear the framebuffer with some other values, let's say colors. this is your code edited with buffer clearing using colors.
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <glfw3.h>
GLFWwindow* window;
#include <glm/glm.hpp>
using namespace glm;
int main( void )
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(800,600,"learnopengl",NULL,NULL);
if (window == NULL)
{
fprintf(stderr,"there is a problem with window creation\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
fprintf(stderr,"Failed to initialize GLEW\n");
return -1;
}
int width, height;
glfwGetFramebufferSize(window,&width,&height);
glViewport(0,0,width,height);
//this is an added line
glClearColor(1, 1, 1, 1); //the RGBA color we will clear with
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
//this is an added line
glClear(GL_COLOR_BUFFER_BIT); //the buffer used to clear with
glfwSwapBuffers(window);
}
glfwTerminate();
}
Hope this answer and this code help other people who may have this situation.
for further information about the framebuffer check this link : https://learnopengl.com/Advanced-OpenGL/Framebuffers

Can't use certain functions in OpenGL (glGenBuffers)

I have seen similar questions to mine else where but none have answered or fixed my problem.
I have GLEW initiated properly, right after the Context creation but before I call glfwMakeContextCurrent()
After I have initiated I try to use glGenBuffers() but it doesn't work. Throws an error.
My OpenGL version is 3.2 so from what I have read I can use this functionality in my program. Please to let me know otherwise though if I can't. I will try to figure out a different way to do this.
I am using Windows 7 and VS2012, and it seems that everything is linked properly. Hope I provided all the info I needed.
#include <stdlib.h>
#include <stdio.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <thread>
int main(){
//Initialize GLFW
if(!glfwInit()){
printf("GLFW was not initialized successfully!\n");
std::this_thread::sleep_for(std::chrono::seconds(5));
exit(EXIT_FAILURE);
}
else{
printf("GLFW was initialized successfully!\n");
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "PONG!", nullptr, nullptr); // Windowed
glewExperimental = GL_TRUE;
if(!glewInit()){
printf("GLEW was not initialized successfully!\n");
std::this_thread::sleep_for(std::chrono::seconds(5));
exit(EXIT_FAILURE);
}
else{
printf("GLEW was initialized successfully!\n");
}
glfwMakeContextCurrent(window);
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
printf("%u\n", vertexbuffer);
fprintf(
stdout,
"INFO: The OpenGL version is: %s\n",
glGetString(GL_VERSION)
);
fprintf(
stdout,
"INFO: The GLEW version is: %s\n",
glewGetString(GLEW_VERSION)
);
while(!glfwWindowShouldClose(window)){
glfwSwapBuffers(window);
glfwPollEvents();
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS){
glfwDestroyWindow(window);
window = glfwCreateWindow(800, 600, "PONG!", nullptr, nullptr);
}
else if (glfwGetKey(window, GLFW_KEY_F) == GLFW_PRESS){
glfwDestroyWindow(window);
window = glfwCreateWindow(800, 600, "PONG!", glfwGetPrimaryMonitor(), nullptr);
}
}
}
I have GLEW initiated properly, right after the Context creation but before I call glfwMakeContextCurrent()
Welp, there's your problem right there:
Successful creation does not change which context is current. Before you can use the newly created context, you need to make it current using glfwMakeContextCurrent.
Call glewInit() after glfwMakeContextCurrent().