Can't draw with opengl version greater then 3.1 with SDL - opengl

I'm making a simple application using OpenGL, GLEW and SDL2 which draws a simple quad on screen (I'm following the example on lazyfoo site with modern OpenGL).
When I use opengl version 3.1 everything works fine, but if I use OpenGL version 3.2+ draw commands don't work (triangle doesn't appear). Does someone know what I am doing wrong?
This is how I setup everything:
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
return false;
}
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
m_pWindow = SDL_CreateWindow("Hello World!", 100, 100, 800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
m_pGLContext = SDL_GL_CreateContext(m_pWindow);
glewExperimental = GL_TRUE;
GLenum glewError = glewInit();
if (glewError != GLEW_OK)
{
return false;
}
//Use Vsync
if (SDL_GL_SetSwapInterval(1) < 0)
{
return false;
}
If you want to check it grab one-file cpp source from http://lazyfoo.net/tutorials/SDL/51_SDL_and_modern_opengl/index.php (on site bottom), and try to change version of opengl from 3.1 to 3.2.

In OpenGL 3.2, the OpenGL profiles were introduced. The core profile actually removes all of the deprecated functions, which breaks compaitibily with older GL functions. The compatibility profile retains backwards compatibility.
To create "modern" OpenGL context, the extensions like GLX_create_context (Unix/X11) or WGL_create_context (Windows) have to be used (and SDL does that for you internally). Citing these extensions specifications gives the answer to your question:
The attribute name GLX_CONTEXT_PROFILE_MASK_ARB requests an OpenGL
context supporting a specific profile of the API. If the
GLX_CONTEXT_CORE_PROFILE_BIT_ARB bit is set in the attribute value,
then a context implementing the core profile of OpenGL is
returned. If the GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB bit is
set, then a context implementing the compatibility profile is
returned. If the requested OpenGL version is less than 3.2,
GLX_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality of the
context is determined solely by the requested version.
[...]
The default value for GLX_CONTEXT_PROFILE_MASK_ARB is
GLX_CONTEXT_CORE_PROFILE_BIT_ARB. All OpenGL 3.2 implementations are
required to implement the core profile, but implementation of the
compatibility profile is optional.
SInce you did not explicitely request a compatibility profile (and SDL does neither), you got a core profile, and it seems like your code is invalid in a core profile.
You might try requesting a compaitbility profile by adding the
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
hint before creating the context.
But be warned that this is not universally supported - MacOS generally supports only GL up to 2.1 OR GL >= 3.2 core profile only. THe open source drivers on Linux only support OpenGL >= 3.2 only in core profile, too. So my recommendation is that you actually fix your code and switch to a core profile.

Related

GLFW window creation options affecting the HarfBuzz

I am using HarfBuzz along with freetype to render regional language hindi.
If I write these three optins for window creation than the font does not render and I only see the blank screen.
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
Without these three options the font renders correctly.
I am curious to know what difference these options make in window creation?
That is because you create a core profile OpenGL Context (GLFW_OPENGL_CORE_PROFILE).
In compare to a compatibility profile context (GLFW_OPENGL_COMPAT_PROFILE), which is default, Legacy OpenGL OpenGL instructions are not valid and cause OpenGL errors.
The main difference is, that you can't use glBegin/glEnd sequences, fixed function attributes (e.g. glVertexPointer) respectively client-side capability or the current matrix stack.
If you want to draw geometry, then you've to create Vertex Array Objects and to use Shader programs.
The complete differences can be seen in the OpenGL 3.3 Compatibility Profile specification or for the most recent OpenGL version OpenGL 4.6 API Compatibility Profile Specification, where the functionality that is only in the compatibility profile specification and not in the core specification is typeset in orange.

Why glDrawElments() is working without using any shader?

I'm trying to debug some shaders but I can't change the one currently loaded. I tried to run without loading any shader, or linking any program and it still working.
I already tried deleting completely the shaders from my HDD. I tried to just call glUseProgram (with any random number including 0) just before calling glDrawElements and it still work. And even if I load any shader it just doesn't make any effect. It still show linking and compile error if I make mistakes in the files but when run the executable it just ignores what is in the shaders.
I draw the vertex with this
void Renderer::renderFrame() {
vao.bind();
glUseProgram(0);
glDrawElements(GL_LINE_LOOP, 3, GL_UNSIGNED_INT, nullptr);
}
and this are my window hints
void App::start() {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 500,500, SDL_WINDOW_RESIZABLE|SDL_WINDOW_OPENGL);
this->context = SDL_GL_CreateContext(window);
glewInit();
glClearColor(0.5,1.0,1.0,1.0);
renderer.init();
}
SDL_GL_SetAttribute() only affects the next SDL_CreateWindow() call.
From the doc wiki:
Use this function to set an OpenGL window attribute before window creation.
So right now you're most likely getting a Compatibility context where shader-less draws are perfectly valid. You can check the value of GL_VERSION to see what you're getting.
If you want a Core context make those SDL_GL_SetAttribute() calls before your SDL_CreateWindow():
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 500,500, SDL_WINDOW_RESIZABLE|SDL_WINDOW_OPENGL);
this->context = SDL_GL_CreateContext(window);
In case no valid shader is binded the default fixed function is usually used (you know GL 1.0 backward compatibility even on core profile sometimes depending on vendor/driver).
So in case your attribute locations matches the used fixed function ones your CPU side code still renders image see:
What are the Attribute locations for fixed function pipeline in OpenGL 4.0++ core profile?
however the locations are not defined by any standard so it is different for any vendor (and can change with time/driver version). Only nVidia defined it and still using it after years...
So its a good idea to check the GLSL compiler/linker log for any shader in development to avoid confusion ... For more info on how to obtain them see:
complete GL+GLSL+VAO/VBO C++ example
btw some gfx drivers support logging and if enabled it will save the GLSL logs into a file on its own... tha can be done for example with nVidia drivers and NVEmulate utility

Unable to compile vertex shader in Maya Plugin

I am writing a plugin on Maya/MacOS which is compiling a vertex shader for OpenGL:
const char* vscode =
{
"#version 150\n"
...
}
However executing the code in Maya gives me
ERROR: 0:1: '' : version '150' is not supported
The OpenGL version returned is 2.1 ATI-1.42.6. I tried to change the OpenGL via glut
glutInitDisplayMode(GLUT_3_2_CORE_PROFILE);
But it does not seem to change the OpenGL Core Profile. How can I change the core profile from within a Maya plugin, or how can I know which "xxx" version would be supported in the shader ?
The OpenGL version returned is 2.1 ATI-1.42.6. I tried to change the OpenGL via glut
Does Maya use GLUT? No! So how so you expect this to work then?
GLUT is a independent library that does window and OpenGL context creation. GLUT is not part of OpenGL and GLUT can not influence OpenGL context management of programs not using GLUT.
Maya does its OpenGL context management internally and when your plugin is called a OpenGL context is already created and the version profile of that particular context set into stone.
But what you can do is you can create a very own OpenGL context, just for your plugin and connect it with the OpenGL context that Maya created (OpenGL context sharing). Doing this is advisable anyway, since this separates OpenGL your plugin uses from OpenGL state Maya uses.
You will have to use the system level OpenGL context management APIs for that. So no GLUT, no GLFW, no SMFL or other helper libraries. Don't worry, it's not too difficult to do. Regarding connecting with the OpenGL context of Maya, every OpenGL context management API has functions to query the currently active OpenGL context and the drawable it's active on. Use those to store which context+drawable pair was active before your plugin got called, then before returning to Maya reset the OpenGL context activation to that pair.

OpenGL ES 2.0 with osmesa

I am attempting to create an OpenGL context with osmesa (off-screen mesa). I wish to use the software implementation of mesa without a window and save the rendered output to a png file.
http://www.mesa3d.org/osmesa.html
I create a GL context with the following:
OSMesaContext context = OSMesaCreateContext(GL_RGBA, NULL);
OSMesaMakeCurrent(context, buffer, GL_UNSIGNED_BYTE, width, height);
However, when I invoke glGetString(GL_VERSION) the version is 2.1 Mesa 10.1.1. As expected, none of my GLSL ES shaders compile. When using SDL I can supply a version hint and create a GLES 2.0 context.
How do I specify the version of the GL context being created by osmesa?
If you look at src/mesa/drivers/osmesa/osmesa.c, around line 745, you can see that it explicitly asks for an OpenGL compatibility profile, which Mesa limits to OpenGL 2.1 and GLSL 130 (see src/mesa/main/version.c line . Replacing API_OPENGL_COMPAT with API_OPENGL_CORE results with the OpenGL version being 0.0 in Mesa 10.6.2, so unfortunately, the simple fix doesn't work. But, setting the MESA_GL_VERSION_OVERRIDE environment variable to "3.3" appears to work. Haven't tested beyond seeing what glGetString(GL_VERSION) returns. Good luck!

nsight - OpenGL 4.2 debugging incompatibility

Whenever I attempt to debug a shader in nvidia nsight I get the following incompatibility in my nvcompatlog.
glDisable (cap = 0x00008620)
glMatrixMode
glPushMatrix
glLoadIdentity
glOrtho
glBegin
glColor4f
glVertex2f
glEnd
glPopMatrix
This is confusing since I am using a 4.2 core profile and not using any deprecated or fixed function calls. At this stage I am just drawing a simple 2D square to the screen and can assure none of the functions listed above are being used.
My real concern is being new to SDL & GLEW I am not sure what functions they are using behind the scene. I have been searching around the web and have found others who are using SDL, GLEW, & Nvidia nsight. This leads me to believe I am overlooking something. Below is a shortened verison of how I am initialing SDL & GLW.
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_Window *_window;
_window = SDL_CreateWindow("Red Square", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED , 200, 200, SDL_WINDOW_OPENGL);
SDL_GLContext glContext = SDL_GL_CreateContext(_window);
glewExperimental = GL_TRUE;
GLenum status = glewInit();
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
In the implementation I have error checking pretty much after every call. I excluded it from the example to reduce the amount of clutter. All the above produce no errors and return valid objects.
After the initialization glewGetString(GLEW_VERSION) returns 4.2.0 NVIDIA 344.75, glewGetString(GLEW_VERSION) returns 1.11.0, and GLEW_VERSION_4_2 returns true.
Any idea on how I can used SDL & GLEW and not have either of these frameworks call deprecated functions?
** Edit **
I have been experiementing with the Dependency Walker here. Looking at the calls through Opengl32.dll none of what is listed is shown as a called module.
For anyone interested, Nsight captures all commands issued to the OpenGL server. Not just those issued through your application. If you have any FPS or recording software enabled, these tend to use deprecated methods drawing to the framebuffer. In my case it was Riva Tuner which displays the FPS on screen for any running games. Disabling it resolved my issue.