I am trying to get an OpenGL context above version 2 on mac using GLFW. My configuration is Mavericks (10.9.1) + XCode and I have an Nvidia Geforce 650M GPU with OpenGL 4.1 Full Profile potentially supported. I use the following code:
static void test_error_cb (int error, const char *description)
{
fprintf(stderr, "%d: %s\n", error, description);
}
int main(void)
{
GLFWwindow* window;
glfwSetErrorCallback(test_error_cb);
// Initialise GLFW
if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW\n");
exit(EXIT_FAILURE);
}
//Request Specific Version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Open OpenGL window
window = glfwCreateWindow(500, 500, "Split view demo", NULL, NULL);
if (!window)
{
fprintf(stderr, "Failed to open GLFW window\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
// Set callback functions
glfwSetFramebufferSizeCallback(window, framebufferSizeFun);
glfwSetWindowRefreshCallback(window, windowRefreshFun);
glfwSetCursorPosCallback(window, cursorPosFun);
glfwSetMouseButtonCallback(window, mouseButtonFun);
glfwSetKeyCallback(window, key_callback);
// Enable vsync
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwGetFramebufferSize(window, &width, &height);
framebufferSizeFun(window, width, height);
//Check Version
int major, minor, rev;
major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
rev = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);
printf("OpenGL version recieved: %d.%d.%d\n", major, minor, rev);
printf("Supported OpenGL is %s\n", (const char*)glGetString(GL_VERSION));
printf("Supported GLSL is %s\n", (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
// Main loop
for (;;)
{
// Only redraw if we need to
if (do_redraw)
{
// Draw all views
drawAllViews();
// Swap buffers
glfwSwapBuffers(window);
do_redraw = 0;
}
// Wait for new events
glfwWaitEvents();
// Check if the window should be closed
if (glfwWindowShouldClose(window))
break;
}
// Close OpenGL window and terminate GLFW
glfwTerminate();
exit(EXIT_SUCCESS);
}
Currently glfwCreateWindow function fails. Without any hints (i.e. no glfwWindowHint calls) I can only have OpenGL 2.1 with glsl version at 1.20. Advise.
A Core context is required to access GL versions greater than 2.1 on OSX.
Uncomment your GLFW_OPENGL_PROFILE hint.
Try adding this before your #include <GLFW/glfw3.h> and uncomment your profile hint.
#define GLFW_INCLUDE_GLCOREARB
Not sure why you're disabling the core profile hint. I don't have an answer, but you might get some more information via the error callback, e.g.,
extern "C"
{
static void test_error_cb (int error, const char *description)
{
fprintf(stderr, "%d: %s\n", error, description);
}
}
...
{
glfwSetErrorCallback(test_error_cb);
if (glfwInit() != GL_TRUE)
{
....
This is a function that can be used prior to glfwInit.
Related
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.
#include "list.h"
int main()
{
//INIT GLFW
glfwInit();
//CREATE WINDOW
const int WINDOW_WIDTH = 640;
const int WINDOW_HEIGHT = 480;
int framebufferWidth = 0;
int framebufferHight = 0;
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH,WINDOW_HEIGHT,"Title", NULL, NULL);
glfwGetFramebufferSize(window, &framebufferWidth, &framebufferHight);
glViewport(0, 0, framebufferWidth, framebufferHight);
glfwMakeContextCurrent(window);//IMPORTIANT!!
//INIT GLEW (NEEDS WINDOW AND OPENGL CONTEXT)
glewExperimental = GL_TRUE;
>//Error
if (glewInit() != GLEW_OK)
{
std::cout << "ERROR::MAIN.CPP::GLEW_INIT_FAILED" << "\n";
glfwTerminate();
}
//MAIN LOOP
while (glfwWindowShouldClose(window))
{
//UPDATE INPUT ---
//UPDATE ---
//DRAW ---
//Clear
//Draw
//End Draw
}
//END OF PROGAM
glfwTerminate();
return 0;
}
glViewport(0, 0, framebufferWidth, framebufferHight); is giving me
Unhandled exception at >0x00007FF704D6E7D9 in OpenzGL4.exe: 0xC0000005: Access violation reading >location >0x0000000000000348.
when I run it.
For any OpenGL instruction is required a valid and current OpenGL Context. Hence glfwMakeContextCurrent hast to be invoked before any OpneGL instruction:
GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH,WINDOW_HEIGHT,"Title", NULL, NULL);
glfwMakeContextCurrent(window); // <----- ADD
glfwGetFramebufferSize(window, &framebufferWidth, &framebufferHight);
glViewport(0, 0, framebufferWidth, framebufferHight);
glfwMakeContextCurrent(window); // <----- DELETE
In addition to what Rabbid76 already wrote in his answer, there is another problem in your code:
glViewport(0, 0, framebufferWidth, framebufferHight);
glfwMakeContextCurrent(window);//IMPORTIANT!!
//INIT GLEW (NEEDS WINDOW AND OPENGL CONTEXT)
glewExperimental = GL_TRUE;
>//Error
if (glewInit() != GLEW_OK) {
std::cout << "ERROR::MAIN.CPP::GLEW_INIT_FAILED" << "\n";
glfwTerminate(); }
Since you use the GLEW OpenGL loader, every gl...() Function name is actually remapped as a preprocessor macro to a function pointer, and glewInit will query all those function pointers (and that needs an active OpenGL context, so it can't be done before the glfwMakeContextCurrent). So it is not enough to move the glViewport after the glfwMakeContextCurrent, you must also move it after glewInit.
And there is a second issue with this code: the glewExperimental = GL_TRUE is an evil hack for a bug in GLEW 1.x with OpenGL core profiles, and it's use can't be discouraged enough. Just update to GLEW 2.x or another loader which is compatible with OpenGL core profile contexts.
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!
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.
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().