Load specific OpenGL version with SDL + GLEW - c++

I am trying to load a specific OpenGL version functions, but it seems that GLEW loads all of the functions regardless what I specify prior to creation of the GL context.
The reason that I know that it's not loading the specified version that I want is because it returns the function pointer to the function that is available in the later version of OpenGL.
glBlendFunci is only available in >= 4.0, whereas I want the 2.1 version of OpenGL, but glBlendFunci gets loaded regardless.
Here's what I'm trying to do:
int main(int argc, char** args)
{
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("Game",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
width, height,
SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GLContext glContext = SDL_GL_CreateContext(window);
glewInit();
std::cout << glBlendFunci << std::endl;
//Initialize();
SDL_GL_DeleteContext(glContext);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
P.S. This is just a some prototyping code and I was just messing around with OpenGL.

The behavior you have observed is well within the spec (see WGL_ARB_create_context or GLX_ARB_create_context):
If a version less than or equal to 3.0 is requested, the context
returned may implement any of the following versions:
Any version no less than that requested and no greater than 3.0.
Version 3.1, if the GL_ARB_compatibility extension is also
implemented.
The compatibility profile of version 3.2 or greater.
What you get is a context which supports GL 2.1 completely, so any code written for GL 2.1 should run - but you may get way more than that - a compatibility profile of the highest GL version your vendor supports is not uncommon.

Related

Trouble Creating a GLFW OpenGL Window in C++

Here is the current bit of code I'm working on:
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL", NULL, NULL);
if (nullptr == window) {
std::cout << "Failed to create GLFW Window" << std::endl;
glfwTerminate();
return EXIT_FAILURE;
}
At runtime, the window is not created, and I get the failure message. I am not understanding why window is a nullptr, when I defined it. Am I missing something?
According to the GLFW documentation, the value for the GLFW_OPENGL_PROFILE window hint must be GLFW_OPENGL_ANY_PROFILE if the requested OpenGL context version is less than 3.2 (and GLFW has a platform-independent check built-in whenever glfwCreateWindow is called).
See: https://www.glfw.org/docs/3.3/window_guide.html#GLFW_OPENGL_PROFILE_hint
GLFW_OPENGL_PROFILE specifies which OpenGL profile to create the context for. Possible values are one of GLFW_OPENGL_CORE_PROFILE or GLFW_OPENGL_COMPAT_PROFILE, or GLFW_OPENGL_ANY_PROFILE to not request a specific profile. If requesting an OpenGL version below 3.2, GLFW_OPENGL_ANY_PROFILE must be used. If OpenGL ES is requested, this hint is ignored.
In particular the part: "If requesting an OpenGL version below 3.2, GLFW_OPENGL_ANY_PROFILE must be used."
You will get a GLFW error in your case. In particular, exactly this one - regardless of the platform/OS, which you would see if you had setup a GLFW error handler function via glfwSetErrorCallback().

Open GL version 2.1 instead of 4.1 in Mac OS 10.15

I'm new to Mac, so I'm not very conversant with the get arounds with this OS.
I wrote a simple Open GL program in Xcode and it ran without issues. However, when I checked the versions using the following code
cout<<glGetString(GL_VENDOR)<<endl;
cout<<glGetString(GL_RENDERER)<<endl;
cout<<glGetString(GL_VERSION)<<endl;
cout<<glGetString(GL_SHADING_LANGUAGE_VERSION)<<endl;
Initialization Code
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
glutCreateWindow("First Test");
initRendering();
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutMainLoop();
I get the following output
ATI Technologies Inc.
AMD Radeon Pro 5300M OpenGL Engine
2.1 ATI-3.10.15
1.20
From forums elsewhere I have read that Mac OS 10.15 supports Open GL version 4.1 and the Graphics card here can certainly support higher versions too.
So my questions are as follows:
Why is it showing 2.1 on my machine
How to fix this? Is there a code that I can type into fix the issue or more software needs to be installed?
Any direction would be great.
Thanks
GLUT is ancient and doesn't support common macOS features such as HiDPI or mouse scrolling. You probably want to look into using the GLFW library instead (see here for what you need to do for a 4.1 context).
However if you really want to use GLUT, you need to add
glutInitContextVersion(4, 1);
glutInitContextProfile(GLUT_CORE_PROFILE);
after glutInit.
Edit: the answer was posted before I know he's using glut, also I recommend GLFW for Modern OpenGL 4.1+
I think you should define the version and create the context first, using some libraries like GLFW and set the OpenGL profile intended to use. also use GLEW/GLAD libraries for GL extensions management.
In case you are using GLFW and GLEW you can add this code to define a version and create a context and a window. then check the version again.
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
using namespace std;
int main()
{
// Initialize GLFW
glfwInit();
// Define version and compatibility settings
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //ver
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // for MAC ONLY
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create OpenGL window and context
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
// Check for window creation failure
if (!window)
{
// Terminate GLFW
glfwTerminate();
return 0;
}
// Initialize GLEW
glewExperimental = GL_TRUE; glewInit();
// your code
cout<<glGetString(GL_VENDOR)<<endl;
cout<<glGetString(GL_RENDERER)<<endl;
cout<<glGetString(GL_VERSION)<<endl;
cout<<glGetString(GL_SHADING_LANGUAGE_VERSION)<<endl;
// Event loop
while(!glfwWindowShouldClose(window))
{
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
// Terminate GLFW
glfwTerminate(); return 0;
}
If you don't have GLFW and GLEW already installed, you can check this tutorial to install them for MacOS : https://riptutorial.com/opengl/example/21105/setup-modern-opengl-4-1-on-macos--xcode--glfw-and-glew- or check this one: https://giovanni.codes/opengl-setup-in-macos/
in case it does not work and still showing 2.1 try to go to the "Energy Saver" in the system settings and deselect the "Automatic graphics switching".

GLEW + SDL Missing OpenGl Version [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I am attempting to get C++ to work with SDL2 and OpenGl on Ubuntu Linux 16.10 x64. When I run my code, I get a "Missing GL version" error. When I search through Google and Stack Exchange I find limited information that applies to my situation. The few "solutions" I find do not work.
List of some of the resources I have already checked:
https://www.opengl.org/discussion_boards/showthread.php/163694-glew-Missing-GL-Version-error
Failed to Initialize GLEW. Missing GL version
Glew initialisation failed : Missing GL version (GLFW)
http://en.sfml-dev.org/forums/index.php?topic=10262.0
The common theme in my research seems to be that I am not properly specifying my OpenGl version, but, I am attempting to do so with my calls to SDL_GL_SetAttribute. It also seems to be a common theme that my context is not properly selected, but, calling SDL_GL_MakeCurrent has no effect.
In addition to this, I have a gtx 1070 with the Nvidia binary blob drivers from the Ubuntu repositories (additional drivers dialog) installed, so, I doubt having the actual OpenGl verion I am requesting available is an issue either. Furthermore, other OpenGl programs (ie. Minecraft) work without issue.
Lastly, very similar code works just fine on other computers (that very similar code does not work on my present computer), and it even gets so far as to create and initalize an OpenGl context correctly on an older computer that does not have my required OpenGl version supported -- those older computers fail later when an unsupported function is called.
What am I doing incorrectly?
I have the following code:
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <sstream>
int main(int argc, char *argv[]){
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_Window *m_window = SDL_CreateWindow(
"test",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
800, 600,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
);
SDL_GLContext m_glContext = SDL_GL_CreateContext(m_window);
SDL_GL_MakeCurrent(m_window, m_glContext); //tried without this code
glewExperimental = GL_TRUE;
int c = glewInit();
if(c != GLEW_OK){
std::ostringstream sout;
sout << "Failed to initialize GLEW: " << glewGetErrorString(c);
throw std::runtime_error(sout.str());
}
}

SDL Can't load OpenGL Context over 2.1 Mac OSX Yosemite

I am running Mac OSX Yosemite Version 10.10 and the latest version of SDL (2.0.3).
I am trying to use at least OpenGL version 3+. Without doing anything, my OpenGL version returns 2.1 INTEL-10.0.86.
The OpenGL commands work, but this is obviously not the version I need.
So, after doing some research I found the way to change the version with SDL is through the SDL_GL_SetAttribute(SDL_GLattr attr, int value) function after you initialize SDL but before you define the context. So here is my code:
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
printf("Failed to initialize SDL. Error (SDL): %s.\n", SDL_GetError());
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); //I read somewhere that this may help
window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, (SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN));
if (!window)
{
printf("Failed to create the window. Error (SDL): %s.\n", SDL_GetError());
return false;
}
context = SDL_GL_CreateContext(window);
Using this code, the OpenGL version reports 4.1 INTEL-10.0.86. This would work well but none of my OpenGL calls work anymore so I checked for an OpenGL error after a function is called and it returns 1282.
The strange thing is that when I change the code to this
...
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
//SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); //I read somewhere that this may help
...
It gives the same output 4.1 INTEL-10.0.86 and returns the same OpenGL error (1282) and none of the OpenGL functions work.
And my last attempt failed as well with a different outcome. Here was my code:
...
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); //I read somewhere that this may help
...
The new OpenGL version returned is null but if I change the major_version to 2 and minor_version to 1 it returns to my original version 2.1 INTEL-10.0.86.
Does anyone know a solution to this problem?
--Edit--
After doing some additional research, if OpenGL returns 1282 after every call the context is not initialized correctly. This leads me to believe that this may be a bug with SDL not correctly creating the context? (I honestly don't know that much so I'm going on a limb). I'll submit a bug to SDL and see if that helps anything.
SDL_GL_CONTEXT_PROFILE_CORE
...
...none of my OpenGL calls [glMatrixMode, glLoadIdentity, glLoadIdentity, glBegin] work anymore...
Those are all deprecated and will not work in a Core context.
If you want to continue using a Core context you'll have to re-write your program to not use deprecated functionality.

Creating an OpenGL 3.2/3.x context in SDL 1.3

I'm facing a problem where SDL says it does not support OpenGL 3.x contexts. I am trying to follow this tutorial: Creating a Cross Platform OpenGL 3.2 Context in SDL (C / SDL). I am using GLEW in this case, but I couldn't get gl3.h to work with this either. This is the code I ended up with:
#include <glew.h>
#include <SDL.h>
int Testing::init()
{
if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
DEBUGLINE("Error initializing SDL.");
printSDLError();
system("pause");
return 1; // Error
}
//Request OpenGL 3.2 context.
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
//set double buffer
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
//Create window
window = SDL_CreateWindow("OpenGL 3.2 test",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
600, 400, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if(window == NULL) return 3; // Error
//Print errors to console if there are any
printSDLError(__LINE__);
//Set up OpenGL context.
glContext = SDL_GL_CreateContext(window);
printSDLError(__LINE__);
if(glContext == NULL)
{
DEBUGLINE("OpenGL context could not be created.");
system("pause");
return 4;
}
//Initialize glew
GLenum err = glewInit();
if(err != GLEW_OK)
{
DEBUGLINE("GLEW unable to be initialized: " << glewGetErrorString(err));
system("pause");
return 2;
}
return 0; // OK code, no error.
}
The only problem that is reported is after trying to call SDL_GL_CreateContext(window), where SDL reports "GL 3.x is not supported". However, both the tutorial and this sample pack (which I have not bothered to test with) report success in combining SDL 1.3 and OpenGL 3.2. I am aware that SDL 1.3 is in the middle of development, but I somewhat doubt that even unintentional support would be removed.
A context is still created, and GLEW is able to initialize just fine. (I can't figure out for the life of me how to see the version of the context that was created, since it's supposed to be the core profile, and I don't know how to find that either. According to the tutorial, SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) doesn't actually do anything, in which case I have no clue how to get the appropriate context created or change the default context.)
EDIT: After some testing thanks to the helpful function Nicol gave me, I have found that, regardless of the parameters I pass to SDL_GL_SetAttribute, the context is always version 1.1. However, putting in any version below 3.0 doesn't spit out an error saying it is not supported. So the problem is that the "core" version SDL sees is only 1.1.
For the record, I am using Visual C++ 2010 express, GLEW 1.7.0, and the latest SDL 1.3 revision. I am fairly new to using all three of these, and I had to manually build the SDL libraries for both 32 and 64 bit versions, so there's a lot that could go wrong. So far however, the 32 and 64 bit versions are doing the exact same thing.
EDIT: I am using an nVidia 360M GPU with the latest driver, which OpenGL Extension Viewer 4.04 reports to have full compatibility up to OpenGL 3.3.
Any help is appreciated.
UPDATE: I have managed to get SDL to stop yelling at me that it doesn't support 3.x contexts. The problem was that the SDL_GL_SetAttribute must be set BEFORE SDL_Init is called:
//Request OpenGL 3.2 context.
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
//Initialize SDL
if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
DEBUGLINE("Error initializing SDL.");
return 1; // Error
}
Unfortunately, GLEW still refuses to acknowledge anything higher than OpenGL 1.1 (only GLEW_VERSION_1_1 returns true), which still has me puzzled. glGetString(GL_VERSION) also reports 1.1.0. It seems that my program simply doesn't know of any higher versions, as if I don't have them installed at all.
since I don't know if you already found a solution, here is mine:
I struggled around a lot today and yesterday with this stuff. Advanced GL functions couldn't be used, so I even debugged into opengl32.dll just to see it really works and wraps the calls into the hardware-specific OpenGL DLL (nvoglnt.dll). So there must have been another cause. There were even tips in the internet to link to opengl32.lib before all other libraries, because ChoosePixelFormat and some other functions are overwritten by each other.
But that wasn't the cause, too. My solution was to enable the accelerated visuals here:
// init SDL
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_HAPTIC | SDL_INIT_TIMER) < 0) {
fprintf(stderr, "Could not init SDL");
return 1;
}
// we must wish our OpenGL Version!!
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
because in the current SDL revision (Dec 15, 2011) he checks for it in SDL_windowsopengl.c
if (_this->gl_config.accelerated >= 0) {
*iAttr++ = WGL_ACCELERATION_ARB;
*iAttr++ = (_this->gl_config.accelerated ? WGL_FULL_ACCELERATION_ARB :
WGL_NO_ACCELERATION_ARB);
}
and this attribute is initialized to -1 if you did not define it on your own.
And: Never set the version attributes before initializing SDL, because settings attributes needs the video backend to be initialized properly!
I hope this helps.
I followed this tutorial. Everything works fine on windowz and linux.
http://people.cs.uct.ac.za/~aflower/tutorials.html