I have started work on a new project with OpenGL 3.3. I was using GLFW and GLEW for window setup and loading of GL functions, but switched to the Unofficial OpenGL SDK instead of GLEW. The problem remained, though:
I was getting a segmentation fault when calling glCreateShader(G_VERTEX_SHADER), and it turned out, that the function pointer was NULL. I later found out that it was caused by an invalid GL Context.
This is the setup code:
#include <glload/gl_3_3.h>
#include <glload/gll.h>
#include <GL/glfw.h>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include "Cube.h"
template <class T>
int arraySize(T *a) {
return (sizeof(a) / sizeof(*a));
}
int main() {
if(!glfwInit()) {
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
// Open a window and create its OpenGL context
if(!glfwOpenWindow(1024, 768, 0,0,0,0, 0,0, GLFW_WINDOW)) {
fprintf(stderr, "Failed to open GLFW window\n");
glfwTerminate();
return -1;
}
if(LoadFunctions() == LS_LOAD_FAILED) {
fprintf(stderr, "Failed to load GL functions.\n");
return -1;
}
I have searched for answers on Google, and on here, but haven't been able to find anything. I also asked in the OpenGL IRC channel on Freenode, and they told me to try the Unofficial SDK instead of GLEW, because GLEW with the core profile is bad. This didn't work, though.
The most weird thing is, that it worked previously, with the exact same setup as now.
By the way, I am using Windows 7 x64 with the newest available drivers.
SOLUTION:
I was being dumb, and calling glCreateShader() before glewInit(). Sorry for being dumb :(
Related
I'm trying to use OpenGL with GLEW and GLFW. However, it appears that I cannot call glewInit() successfully and I get the following error message: GLEW error (1): Missing GL version. Similar questions at Stackoverflow haven't solved my problem.
When building my project, I am including the glew.c file and the directory where glew.h is.
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main()
{
glfwInit();
glfwWindowHint(GLFW_SAMPLES, 0);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Testing", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewExperimental = true;
GLenum glewErr = glewInit();
if (glewErr != GLEW_OK)
{
std::cerr << "GLEW error (" << glewErr << "): " << glewGetErrorString(glewErr) << std::endl;
glfwTerminate();
return -1;
}
// Next, I paint some stuff using OpenGL ...
}
Everything looks ok in the code. Furthermore, for some reason, if I use GLAD instead of GLEW, my code works just fine.
System: Ubuntu 18.04.5 LTS.
OGL version: 3.3.0 NVIDIA 340.108
OGL vendor: NVIDIA Corporation
Renderer: GeForce 820M/PCIe/SSE2
GLSL version: 3.30 NVIDIA via Cg compiler
UPDATE:
Diving deep into glew.c code I found where the error pops up, though I can't still understand why. Here it is the piece of code
static GLenum GLEWAPIENTRY glewContextInit ()
{
PFNGLGETSTRINGPROC getString;
const GLubyte* s;
GLuint dot;
#ifdef _WIN32
getString = glGetString; // Not executed, I'm on Ubuntu
#else
getString = (PFNGLGETSTRINGPROC) glewGetProcAddress((const GLubyte*)"glGetString");
if (!getString)
return GLEW_ERROR_NO_GL_VERSION;
#endif
/* query opengl version */
s = getString(GL_VERSION); // <<< ERROR: s gets a null pointer
dot = _glewStrCLen(s, '.');
if (dot == 0)
return GLEW_ERROR_NO_GL_VERSION; // <<< Function escapes here
// ... more statement down here
}
I tried with following methods -
1. using glew
2. using glut
both almost similar ways as follows -
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main(int agrc, char **argv)
{
//do windowing related stuff here
if ( !glfwInit())
{
printf("Error: Failed to initialize GLFW\n");
return -1;
}
GLFWwindow* window = glfwCreateWindow(800, 600, "Triangle", NULL, NULL);
if (window == NULL)
{
printf("Failed to create GLFW window\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
printf("Error: Failed to initialize GLEW\n");
return -1;
}
printf("GL version: %s\n", glGetString(GL_VERSION));
printf("GL shading language version: %s\n",
glGetString(GL_SHADING_LANGUAGE_VERSION));
}
Question - Is it possible to check GL and GLSL Version with creating native window?
As per my understanding it is necessary to create GL context which is usually done by creating a window, Please tell me alternative without creating window.
According to the OpenGL Wiki FAQ (emphasis mine).
You must create a GL context in order for your GL function calls to make sense. You can't just write a minimal program such as this:
int main(int argc, char **argv)
{
char *GL_version=(char *)glGetString(GL_VERSION);
char *GL_vendor=(char *)glGetString(GL_VENDOR);
char *GL_renderer=(char *)glGetString(GL_RENDERER);
return 0;
}
In the above, the programmer simply wants to get information about this system (without rendering anything) but it simply won't work because no communication has been established with the GL driver. The GL driver also needs to allocate resources with respect to the window such as a backbuffer. Based on the pixelformat you have chosen, there can be a color buffer with some format such as GL_BGRA8. There may or may not be a depth buffer. The depth might contain 24 bits. There might be a 8 bit stencil. There might be an accumulation buffer. Perhaps the pixelformat you have chosen can do multisampling. Up until now, no one has introduced a windowless context.
You must create a window. You must select a pixelformat. You must create a GL context. You must make the GL context current (wglMakeCurrent for Windows and glXMakeCurrent for *nix).
That said, if you're just looking to avoid a temporary window popping up, create a non-visible window, so the end-user doesn't have any idea that you're creating the window. In GLFW, it appears you can do this by setting the window hint GLFW_VISIBLE to false with glfwWindowHint before creating the window. All other windowing systems I've worked with have a similar concept of setting the visibility of a window.
I can't open an OpenGL window, due to following error message (I'm on Windows):
GLFW Error Code 65543: WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable.
It is likely that my problem is a driver problem. I tried to update them (using Intel Driver Update Utility), but it didn't do the trick (and my driver seemed to be already up to date). I use built-in Intel HD Graphics 3000. I also installed a OpenGL viewer, which tells me that my OpenGL version is 3.1).
Also, I tried this solution.
The whole C++ code is quite huge so I won't copy it all , but here is the interesting part:
if( !glfwInit() )
{
std::cerr<<"Failed to initialize GLFW\n"<<std::endl;
return -1;
}
glfwSetErrorCallback(glfwErrorCallback);
// Create the OpenGL window
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_SAMPLES, 4);
//Those stop GLFW from initializing successfully?
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Open OpenGL fullscreen window
gGLFWWindow = glfwCreateWindow(gWidth,gHeight,"GLFW OpenGL Window",nullptr,nullptr);
if(!gGLFWWindow)
{
std::cerr<<"Failed to open GLFW window\n"<<std::endl;
glfwTerminate();
return -1;
}
// Disable VSync (we want to get as high FPS as possible!)
glfwMakeContextCurrent(gGLFWWindow);
glfwSwapInterval( 1 );
// Setting this is necessary for core profile (tested with MSVC 2013 x64, Windows 7)
glewExperimental = GL_TRUE;
// GLEW wraps all OpenGL functions and extensions
GLenum err = glewInit();
if(err != GLEW_OK)
{
std::cerr<<"Failed to initialize GLEW"<<std::endl;
std::cerr<<(char*)glewGetErrorString(err)<<std::endl;
glfwTerminate();
return -1;
}
glGetError(); //GLEW might cause an 'invalid enum' error, safely ignore it?
// Print OpenGL context information to console
ogl::printContextInformation();
// Perform our initialization (OpenGL states, shader, camera, geometry)
if(!init())
return -1;
It fails at this line :
gGLFWWindow = glfwCreateWindow(gWidth,gHeight,"GLFW OpenGL Window",nullptr,nullptr);
Does anyone have an idea of what I could do to solve this issue?
The answer is : I was requesting a Core 3.3 context whereas my version was OpenGL 3.1.
Deleting/commenting those lines will do the trick :
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
I to had the same problem because my last machine has an openGl of version 3.3 and now because the one am using now has but an openGl 3.1 made me almost got frustrated
But De-comenting the "window hints", it solves the problem
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I'm trying to follow this tutorial for OpenGL. I originally copied the code by hand, but that wasn't working, so I've copy-pasted the code straight from the website. I keep getting this error:
[Linker error] undefined reference to 'glfwInit'
from this code (which feels longer than necessary):
//C++ standard headers
#include <stdio.h>
#include <stdlib.h>
//GLEW header
#include <GL/glew.h>
//GLFW header
#include <GL/glfw3.h>
int main()
{
if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL
// Open a window and create its OpenGL context
GLFWwindow* window; // (In the accompanying source code, this variable is global)
window = glfwCreateWindow( 1024, 768, "Tutorial 01", NULL, NULL);
if( window == NULL )
{
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window); // Initialize GLEW
glewExperimental=true; // Needed in core profile
if (glewInit() != GLEW_OK)
{
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
do{
// Draw nothing, see you in tutorial 2 !
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
}
// Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
}
I've got no idea why it's not compiling. Anyone know what's going on?
EDIT: I'm using Dev-C++, as stated in the title.
undefined reference to 'glfwInit'
means that the linker did not find the library where glfwInit() is defined. You have to add glfw3.a to your linker input. Indeed, Dev-C++ use MinGW so unlike Visual Studio, the libraries can not be .lib.
To do that with Dev-C++, go to your 'project options', 'parameters', and 'add a library'. Then browse the explorer to find the glfw3.a I mentioned (usually in GLFW-<version>/lib/).
I am sure that everything is linked correcly. I initially was using glload and glfw from the Unofficial GLSDK but then I decided to do away with glload which meant that I had to use glew in order to get at the modern headers.
#include <GL/glew.h>
#include <GL/glfw.h>
I have included glew before glfw as per the instructions.
During run time the OpenGL window opens
//(relevant code)
if(!glewInit()) {return -1; }
if(!glfwInit()) {return -1; }
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// also tried glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
if(!glfwOpenWindow(1024, 768, 8, 8, 8, 8, 24, 8, GLFW_WINDOW)){
glfwTerminate();
return -1;
}
glfwSetWindowTitle("OpenGL 3.2");
//init method
glGenVertexArrays(1, &vao); //<< Access violation here.
Any ideas what my problem is here?
I have looked at. "Access violation using VBO with glew" But it was no help.
glewInit is to be called after a OpenGL context has been created and bound to the current thread, i.e. after glfwOpenWindow in your case.
A little late, but figured I'd pipe in anyways.
As mentioned by datenwolf, in your relevant code posted the glewInit() should return an error due to it's positioning.
The other potential issue you could be encountering is described on http://www.opengl.org/wiki/OpenGL_Loading_Library under the GLEW section.
copy-paste from above:
GLEW has a problem with core contexts.
It calls glGetString(GL_EXTENSIONS),
which causes GL_INVALID_ENUM on GL 3.2+ core context as soon as glewInit() is called.
Solution for GLEW (also provided by above link) is to enable 'EXPERIMENTAL' support. Ex:
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if( err != GLEW_OK )
{
printf("GlewInit error");
exit(1);
}
Also late but for anyone still looking
glewExperimental = GL_TRUE;
Before initializing the context was got rid of the access violation error, but instead made the program exit with a GL_INVALID_ENUM error. With GLFW, I had to additionally comment out the window hints:
//glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
//glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
//glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
The programs then started compiling!