When I attempt to generate a buffer by executing the glGenBuffer() function - no function like that is found.
Some functions are still working, and from what I see most do work, for instance the following code works perfectly:
#include <iostream>
#include <GLFW/glfw3.h>
using namespace std;
class Window_Manager
{
public:
GLFWwindow* window;
int Create_Window(int width, int height, const char* title) {
if (!glfwInit()) {
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
glfwWindowHint(GLFW_FOCUSED, GL_TRUE);
window = glfwCreateWindow(width, height, title, NULL, NULL);
if (window == NULL) {
cout << "Failed to create a window! Aborting early..." << endl;
Terminate_Window(window);
return -1;
}
glfwMakeContextCurrent(window);
glViewport(0, 0, width, height);
return 1;
}
void Terminate_Window(GLFWwindow* window) {
glfwSetWindowShouldClose(window, GL_TRUE);
glfwTerminate();
}
};
but this code does not:
#include <GLFW/glfw3.h>
#include <Engine_Manager.h>
#include <iostream>
using namespace std;
class Shape2D
{
int VBO;
int Setting_Up(){
VBO = glGenBuffer();
return 1;
}
};
In addition to replacing glGenBuffer with glGenBuffers(1, &VBO) as rpress mentioned in the comments, OpenGL is a weird library in that you have to load most of the functions dynamically.
The exact details differ from platform to platform. On Windows, for example, you can use wglGetProcAddress to get pointers to desired functions.
Rather than do it manually, GLEW is an excellent library for getting OpenGL function pointers easily. Other options are documented on the OpenGL wiki.
Related
It seems that I am having a seg fault while using GLFW and OpenGL on ArchLinux, DWM (fully updated and patched).
I retraced the code and it is having the segFault in the glfwSwapBuffers(window).
Here is my code :
main.cpp
#include <iostream>
#include "gui/window.h"
int main(int, char**) {
Window window("Test GL", 800, 600);
if(!window.hasCorrectlyLoaded()) {
return 1;
}
while (!window.shouldClose())
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
window.pollEvents();
}
}
window.h
#ifndef __WINDOW_H__
#define __WINDOW_H__
#include <string>
#include <glad/gl.h>
#include <GLFW/glfw3.h>
class Window {
private:
GLFWwindow *window;
bool correctlyLoaded;
public:
Window(const std::string&, int, int);
~Window();
const bool hasCorrectlyLoaded();
const bool shouldClose();
const void pollEvents();
};
#endif // __WINDOW_H__
window.cpp
#include "window.h"
#include <spdlog/spdlog.h>
Window::Window(const std::string& title, int width, int height)
{
correctlyLoaded = false;
if(!glfwInit()) {
spdlog::default_logger()->critical("Could not load GLFW");
return;
}
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, GLFW_TRUE);
GLFWwindow* window = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
if (!window)
{
spdlog::default_logger()->critical("Failed to create GLFW window !");
return;
}
glfwMakeContextCurrent(window);
if (!gladLoadGL(glfwGetProcAddress))
{
spdlog::default_logger()->critical("Failed to load OpenGL !");
return;
}
spdlog::default_logger()->info("Loaded OpenGL {}", glfwGetVersionString());
glViewport(0, 0, width, height);
correctlyLoaded = true;
}
const void Window::pollEvents()
{
glfwSwapBuffers(window);
glfwPollEvents(); //<- Seg fault here
}
Window::~Window()
{
glfwTerminate();
}
const bool Window::hasCorrectlyLoaded()
{
return correctlyLoaded;
}
const bool Window::shouldClose()
{
return glfwWindowShouldClose(window);
}
While further researching, I stumbled upon an answer that told me to set the glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API) window hint but I still got a segfault, but at a different place :
GLFW source code
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
"Cannot swap buffers of a window that has no OpenGL or OpenGL ES context"); //<- Seg fault without window hint
return;
}
window->context.swapBuffers(window); //<- Seg fault with window hint
}
Here is the output I get from the logging :
[2022-05-24 20:01:04.252] [info] Loaded OpenGL 3.4.0 X11 GLX Null EGL OSMesa monotonic
[1] 432406 segmentation fault (core dumped) /home/lygaen/code/testgl/build/testgl
Your problem occurs in Window.cpp, at this line:
//...
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
GLFWwindow* window = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr); //<---
if (!window)
{
//...
You've redeclared window as a local variable to this constructor, and as a result, the pointer never escapes the constructor, and is dangled.
A good habit when trying to assign class members is to use the this keyword. It is often redundant, but it does help indicate intent. So the code should be changed to this:
//...
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
this->window = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr); //<---
if (!this->window)
{
//...
If your style guidelines don't permit it, you can omit the this->; the only important part is that you're not declaring an entirely new variable that's shadowing the class member.
I tried doing OpenGL using GLFW. I was beginning to make a window
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
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(500, 500, "Test", NULL, NULL);
if (window == NULL) {
std::cout << "GLAD failed.";
}
glfwMakeContextCurrent(window);
void frameBufferSizeCallback(GLFWwindow* window,int width,int height);
glfwSetFramebufferSizeCallback(window, frameBufferSizeCallback);
glViewport(0, 0, 500, 500);//Error here
while (!glfwWindowShouldClose(window)) {
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void frameBufferSizeCallback(GLFWwindow* window,int width,int height) {
glViewport(0,0,width,height);
}
I get some error saying Exception thrown at 0x00000000 in OpenGLTest0.exe: 0xC0000005: Access violation executing location 0x00000000. And the window I created doesn't even respond to anything including Task Manager "end task. I was using Visual Studio 2017 and had to "end task" the whole aplication in order to remove the window. Also I am on Windows 10.
Could somebody tell me where I am wrong? I thank you in advance!
You need to initalize the glad library, without that it can't load in the function pointers.
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
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, ...)
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
I'm using Visual Studio 2013, and as I am learning OpenGL 3.3 I thought best to use
#define GLFW_INCLUDE_GLCOREARB
#include <GLFW/glfw3.h>
to force 'intellisense' to not even show old depreciated functions such as glVertex2f etc...
However the inclusion of said #define prevents any gl* functions from showing up. Even glViewport is undefined. When attempting to compile a simple application I get among many errors
error C3861: 'glViewport': identifier not found
glcorearb.h is my include files path though, downloaded from http://www.opengl.org/registry/api/GL/glcorearb.h only yesterday.
I might be doing something completely wrong here. But here is my full source code...
// Include standard headers
#include <stdio.h>
#include <stdlib.h>
#define GLFW_INCLUDE_GLCOREARB
// Include GLFW3
#include <GLFW/glfw3.h>
//Error Callback - Outputs to STDERR
static void error_callback(int error, const char* description)
{
fputs(description, stderr);
}
//Key Press Callback
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(){
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
// Initialise GLFW
if (!glfwInit())
{
fputs("Failed to initialize GLFW\n", stderr);
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_SAMPLES, 2); // 2x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL
// Open a window and create its OpenGL context
window = glfwCreateWindow(640, 480, "Test", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
while (!glfwWindowShouldClose(window))
{
float ratio;
int width, height;
glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float)height;
glViewport(0, 0, width, height);
glClearColor(0.5f, 0.7f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}