OpenGL Invalid Operation with GenVertexArrays - c++

I am creating a grid in opengl, very simple, but am getting an error when I call gl::GenVertexArrays. Below is the code. I am using glfw3.
GLuint vao = 0;
check_gl_error();
gl::GenVertexArrays(1, &vao);
check_gl_error(); //the error is caught here and its a INVALID_OPERATION
gl::BindVertexArray(vao);
check_gl_error();
I do not have much experience with OpenGL, however I have used opengl on the same computer using glfw and have had projects working with GenVertexArrays.
EDIT:
My program is setup with
if (!glfwInit()) {
std::cout << "Init GLFW failed" << std::endl;
exit(EXIT_FAILURE);
}
GLFWwindow* window = glfwCreateWindow(800, 800, "My Title", NULL, NULL); //glfwGetPrimaryMonitor() full screen
if (!window) {
std::cout << "Init window failed" << std::endl;
glfwTerminate();
exit(EXIT_FAILURE);
}
gl::sys::LoadFunctions();
//check_gl_error();
glfwMakeContextCurrent(window);
check_gl_error();
glfwSwapInterval(1);
check_gl_error();
GLuint programID = gl::CreateProgram();

Do you use GLEW or glLoadGen or something? You need to tell it to update its entry points again after you make the actual context current.
In Windows, only ancient OpenGL is available until you make a more modern context current. Only then will the higher-version entry points become available for lookup by GLEW/glLoadGen's code.
In other words, all those OpenGL function pointers suddenly may point to different code, because the OpenGL version changed. That is how wgl works.

Related

Why is OpenGL telling me that terminate called after throwing an instance of 'int' after running it?

So I tried to make an OpenGL project with GLFW and glad in visual studio code, but it would throw and error when I would compile and run the program.
I tried to make 3 triangles in a window, it worked so I tried organizing the VBO, VAO, EBO, shaderProgram, vertexShaderSource, and fragmentShaderSource into individual files, and compiled and ran it, I expected the usual result but would give me a window that is not responding, then it would terminate and give out an error. I'm not sure witch of the files are causing this, but my guess is the main.cpp file:
#include"header/shaderClass.h"
#include"header/VAO.h"
#include"header/VBO.h"
#include"header/EBO.h"
//some vertex and indices arrays here
int main()
{
// Initialize GLFW
glfwInit();
// Tell GLFW what version of OpenGL we are using
// In this case we are using OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// Tell GLFW we are using the CORE profile
// So that means we only have the modern functions
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Create a GLFWwindow object of 800 by 800 pixels, naming it "YoutubeOpenGL"
GLFWwindow* window = glfwCreateWindow(800, 800, "YoutubeOpenGL", NULL, NULL);
// Error check if the window fails to create
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// Introduce the window into the current context
glfwMakeContextCurrent(window);
//Load GLAD so it configures OpenGL
gladLoadGL();
// Specify the viewport of OpenGL in the Window
// In this case the viewport goes from x = 0, y = 0, to x = 800, y = 800
glViewport(0, 0, 800, 800);
// Generates Shader object using shaders defualt.vert and default.frag
Shader shaderProgram("default.vert", "default.frag");
// Generates Vertex Array Object and binds it
VAO VAO1;
VAO1.Bind();
// Generates Vertex Buffer Object and links it to vertices
VBO VBO1(vertices, sizeof(vertices));
// Generates Element Buffer Object and links it to indices
EBO EBO1(indices, sizeof(indices));
// Links VBO to VAO
VAO1.LinkVBO(VBO1, 0);
// Unbind all to prevent accidentally modifying them
VAO1.Unbind();
VBO1.Unbind();
EBO1.Unbind();
// Main while loop
while (!glfwWindowShouldClose(window))
{
// Specify the color of the background
glClearColor(0.07f, 0.13f, 0.17f, 1.0f);
// Clean the back buffer and assign the new color to it
glClear(GL_COLOR_BUFFER_BIT);
// Tell OpenGL which Shader Program we want to use
shaderProgram.Activate();
// Bind the VAO so OpenGL knows to use it
VAO1.Bind();
// Draw primitives, number of indices, datatype of indices, index of indices
glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0);
// Swap the back buffer with the front buffer
glfwSwapBuffers(window);
// Take care of all GLFW events
glfwPollEvents();
}
// Delete all the objects we've created
VAO1.Delete();
VBO1.Delete();
EBO1.Delete();
shaderProgram.Delete();
// Delete window before ending the program
glfwDestroyWindow(window);
// Terminate GLFW before ending the program
glfwTerminate();
return 0;
}

Generated window with GLFW, background color not changing

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.

Regular window screen capture using openGL

I'm trying to my desktop image capture. (All images, including the desktop output to the monitor)
It's easy using window API (BitBlt or CImageClass) and it's not the way I want.
I want do it using opengl. so I found glReadPixel funtion and window TRANSPARENT.
But it just read pixel own Windows application screen.(Save as bmp file and check)
Initialize()
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);
if (glfwGetWindowAttrib(GLwindow, GLFW_TRANSPARENT_FRAMEBUFFER))
{
//...
}
glfwSetWindowOpacity(GLwindow, 0.0f);
auto Mode = glfwGetVideoMode(Monitor[0]);
glfwMakeContextCurrent(GLwindow);
glfwSetKeyCallback(GLwindow, keyCallback);
glewExperimental = GL_TRUE;
GLenum errorCode = glewInit();
if (GLEW_OK != errorCode) {
std::cerr << "Error: GLEW - " << glewGetErrorString(errorCode) << std::endl;
glfwTerminate();
exit(EXIT_FAILURE);
}
if (!GLEW_VERSION_3_3) {
std::cerr << "OpenGL 3.3 API is not available." << std::endl;
glfwTerminate();
exit(EXIT_FAILURE);
}
glViewport(0, 0, nWidth, nHeight);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
std::cerr << "Error: " << std::endl;
}
return true;
Roop
while (!glfwWindowShouldClose(GLwindow)) {
Sleep(10);
glClearColor(0.0f, 0.3f, 0.3f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT);
unsigned char *image = (unsigned char*)malloc(sizeof(unsigned char)*nWidth*nHeight * 3);
glReadPixels(0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, image);
glfwPollEvents();
}
return true;
Q1. Is it possible desktop capture(Full Image GPU output) with OPENGL?
Q2. If Q1 is possible, Should I use FBO and PBO GL_BACK??
Q3. How to access to mother window or GPU adapter? >> GL seems to strongly reject this.(I don't want any rendering, just read pixel data from GPU(Desktop image. not rendered by my application.)(If it is possible ...))
Anybody shows to me about link or idea?
What you're asking for is something completely outside the scope of OpenGL. OpenGL is designed to be a platform-agnostic API for applications to talk about drawing stuff into framebuffers in an abstract fashion. OpenGL has no notion of windows*, screens, or a desktop. OpenGL doesn't operate at a level where such concepts exist. Heck, OpenGL doesn't even know what a GPU is. OpenGL is supposed to be initialized through platform-specific mechanisms to establish a context which assigns actual meaning to OpenGL API calls. As far as I know, there is no way to set up an OpenGL context with a framebuffer whose contents would somehow correspond to the desktop on Windows (or any other platform I'm aware of). As far as my understanding goes, this wouldn't really make sense…
To do what you want to do, you'll have to rely on the respective platform-specific APIs. The probably simplest way on Windows is to get an HDC for the entire desktop and BitBlt from there. See, e.g., this question for more on that. A more modern approach would be to use the DXGI Desktop Duplication API.
(*) yes, I know the OpenGL specification technically does talk about "windows" in a few places; but it only really does so when it's talking about all the things it's not responsible for…
I'm trying to my desktop image capture. (All images, including the desktop output to the monitor)
It's easy using window API (BitBlt or CImageClass) and it's not the way I want.
But it's the way it's supposed to be done.
I want do it using opengl. so I found glReadPixel funtion
You can't. OpenGL doesn't "know" about the desktop, or other windows (or actually what windows are at all). The function glReadPixels will work reliably only for images that have been drawn with OpenGL itself.
You can't use OpenGL to take screenshots! On older computers it might seem to work, but that's only because of their older memory management where when you create a new window, its memory will be "cut" from what was below and if you read that, it looks like a way to make screenshots. But it is not.

glew causes screen to flicker between red and black. glad works

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 ?

Cannot create GLFWwindow in C++ - glfwCreateWindow returns nullptr?

After running several tests on the code, I have determined that both GLFW and GLEW are initialised successfully yet when I try and create a GLFWwindow* object to be used with GLFW functions, the glfwCreateWindow() function returns a nullptr. Why is this and how do I fix it? Here is my code:
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
const GLuint windowWidth = 500, windowHeight = 500;
int main()
{
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);
GLFWwindow* window = glfwCreateWindow(windowWidth, windowHeight, "Learn OpenGL", nullptr, nullptr);
if (window == nullptr) {
std::cout << "Failed to create GLFW window!" << std::endl;
char myvar1; std::cin >> myvar1;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (glewInit() != GL_TRUE) {
std::cout << "Failed to initialize GLEW" << std::endl;
char myvar2; std::cin >> myvar2;
return -1;
}
glViewport(0, 0, windowWidth, windowHeight);
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
This is probably because you are specifying version 3.3 for the context creation and your opengl version is lower than 3.3.
OpenGL: GLFW_CONTEXT_VERSION_MAJOR and GLFW_CONTEXT_VERSION_MINOR are not hard constraints, but creation will fail if the OpenGL version of the created context is less than the one requested.
This might happen if you are using a laptop that has 2 GPU's. They do that for power-consumption reasons, most applications will be run with the standard GPU and for games for example it will use the high performance one.
For example my laptop has a built-in Intel(R) HD Graphics 3000(3.1 opengl version) GPU and a NVIDIA geforce gt 630M(4.4 opengl version) GPU.
You can see if your laptop has this functionality if you right click on an application shortcut and have the option "run with graphics processor": - "High performance (NVIDIA) processor" - "Integrated graphics (default)"
The problem is that the editor(eclipse/ms visual studio, etc..)(in which you run your code) will use the default one and usually has a much lower version of opengl than your other GPU.
You can fix this by always running your editor program with your high performance GPU.
If you're not using a laptop or only have one GPU then try updating your drivers.