1
\$\begingroup\$

I am just starting with OpenGL using c++ on Ubuntu 18.04. The problem I have is that when I try to link Geometry Shader in my main program, the following function call is unable to create an object (and hence returns 0)

GLuint ShaderObj = glCreateShader(ShaderType);

when ShaderType = GL_GEOMETRY_SHADER. The error log thrown is: "Error creating shader type 36313". Here, 36313 is the enum value for GL_GEOMETRY_SHADER.

NOTE: My program runs successfully (with a differing functionality) when I remove the geometry shader, while keeping the fragment & vertex shaders intact.

The following is the source code for my geometry shader:

#version 130

layout (triangles) in;
layout (triangle_strip, max_vertices = 4) out;

void main() {
    gl_Position = gl_in[0].gl_Position;
    EmitVertex();
    gl_Position = gl_in[1].gl_Position;
    EmitVertex();
    gl_Position = gl_in[2].gl_Position;
    EmitVertex();
    EndPrimitive();
}

The flow of the main code is as follows:

During CompileShaders(), the code calls AddShader(ShaderProgram, gs.c_str(), GL_GEOMETRY_SHADER). The following are the first few lines in this function.

static void AddShader(GLuint ShaderProgram, const char* pShaderText, GLenum ShaderType) {
    GLuint ShaderObj = glCreateShader(ShaderType);
    if (ShaderObj == 0) {
        fprintf(stderr, "Error creating shader type %d\n", ShaderType);
        exit(0);
    }
...
}

Here glCreateShader() returns 0 which is why in the following if condition an error is thrown as mentioned previously.

The following are the version details of my setup.

    GLX version: 1.4
        Max core profile version: 4.6
        Max compat profile version: 3.0
        Max GLES1 profile version: 1.1
        Max GLES[23] profile version: 3.1
    OpenGL core profile version string: 4.6 (Core Profile) Mesa 20.0.8
    OpenGL core profile shading language version string: 4.60
    OpenGL version string: 3.0 Mesa 20.0.8
    OpenGL shading language version string: 1.30
    OpenGL ES profile version string: OpenGL ES 3.1 Mesa 20.0.8
    OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10

The following is my hardware information.

00:02.0 VGA compatible controller: Intel Corporation HD Graphics 5500 (rev 09)
    Subsystem: Dell HD Graphics 5500
    Kernel driver in use: i915
    Kernel modules: i915
--
08:00.0 3D controller: NVIDIA Corporation GF117M [GeForce 610M/710M/810M/820M / GT 620M/625M/630M/720M] (rev a1)
    Subsystem: Dell GeForce 820M
    Kernel driver in use: nouveau
    Kernel modules: nvidiafb, nouveau

I think this might be some version error. But I am not sure. I would be really, really grateful if someone could help me out with this.

\$\endgroup\$
3
  • \$\begingroup\$ #version 130 in the shader seems irritating but unrelated to that error. Make it the same as your context. Sure your context is a 4.6 (or at least >= 3.3) ? Is the version output from the context of your program or from the driver info from the OS ? Do you have a debug context that could tell you more about what's going on ? \$\endgroup\$ – user144188 Oct 15 '20 at 20:39
  • \$\begingroup\$ Btw, my old notebook has a HD5400 and it only supports up to 4.3 (or 4.5 ?). Which is not problem for your case. be sure to obtain a >= 3.3 context and setup a debug context with a proper error callback and output. It doesn't look like you have at it makes your life so much easier :-) \$\endgroup\$ – user144188 Oct 15 '20 at 20:49
  • \$\begingroup\$ @a_donda Thanks for your suggestions! The version output I specified was from the OS (terminal). From the context of my program, it is "GL version: 3.0 Mesa 20.0.8". On making a call to glGetError() just after glCreateShader(), the error thrown is "1280" (enumeration parameter (GL_GEOMETRY_SHADER in my case) is not legal). I just got introduced to debugging on OpenGL due to you. Thanks!!! Now, how do I get a context >= 3.3? \$\endgroup\$ – Tanay Oct 16 '20 at 6:22
2
\$\begingroup\$

This is less a specific answer to the question, but a general hint on how to set up an OpenGL context because I feel it will answer the question automatically. The same procedure is used for instance by 'learnopengl.com' and possibly others I don't know. My system is a Debian 10, but it should work on Windows as well.

We'll setup an OpenGL context and enable debug messages. This works from OpenGL 4.3 on, which should not be a problem even on old systems. I'll use GLFW3 (www.glfw.org) as the windowing and input event handling api to avoid messing with system specific C-apis, glad as the GL library loader (glad.dav1d.de/), and the code snippets are plain C. I installed glfw via the package manager (Windows users will have to read the installation documentation), and glad comes as a header and a c file.

1 - Headers to be included:

#include "glad/glad.h"
#define GLFW_NO_INCLUDE_API
#include <GLFW/glfw3.h>

Note you will have to link to glfw and under Linux to dl for dynamic loading.

2 - Initialize glfw, load opengl functions:

glfwSetErrorCallback( glfw_error_callback );
if( GL_TRUE != glfwInit() ) {
    // didn't work, can't carry on
}
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 4 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 5 );
glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE );
glfwWindowHint( GLFW_CLIENT_API, GLFW_OPENGL_API );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );

Set other specific hints if needed, then open the window:

window = glfwCreateWindow( width, height, title, NULL, NULL );
if( !window ) {
    // didn't work, but there should be an error message by the error callback
    glfwTerminate();
    return false;
}
glfwMakeContextCurrent( window );
// Load gl function pointers
if( !gladLoadGLLoader( (GLADloadproc)glfwGetProcAddress ) ) {
    // glad couldn't load the function pointers, cleanup and get out
    glfwDestroyWindow( window );
    glfwTerminate();
    return false;
}

Now initalize debug output:

GLint flags;
glGetIntegerv( GL_CONTEXT_FLAGS, &flags );
if( flags & GL_CONTEXT_FLAG_DEBUG_BIT ) {
    glEnable( GL_DEBUG_OUTPUT );
    // Envoke callback directly in case of error
    glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS );
    glDebugMessageCallback( glDebugOutput, NULL );
    glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE );
} else
    // say that debug context could not be created but life goes on without it

Now two things are still missing, the glfw_debug_callback and the glDebugCallback. I leave the function body out because mine is pretty verbose:

void error_callback( int error, const char *msg ) {
    // format and output/log the message
}

as well as

void APIENTRY glDebugOutput( GLenum source, GLenum type, GLuint id, GLenum severity,
    GLsizei length, const GLchar *message, const void *userParam ) {
// Ignore non-significant error/warning codes
// pseudcode: if( id == 131169 || id = whateverelse ) return;
/* stitch togehter and format a msg from source: 
   GL_DEBUG_SOURCE_API, GL_DEBUG_SOURCE_WINDOW_SYSTEM,
   GL_DEBUG_SOURCE_SHADER_COMPILER, GL_DEBUG_SOURCE_THIRD_PARTY,
   GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_SOURCE_OTHER
   type:
   GL_DEBUG_TYPE_ERROR, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR;
   GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, GL_DEBUG_TYPE_PORTABILITY,
   GL_DEBUG_TYPE_PERFORMANCE, GL_DEBUG_TYPE_MARKER,
   GL_DEBUG_TYPE_PUSH_GROUP, GL_DEBUG_TYPE_POP_GROUP,
   GL_DEBUG_TYPE_OTHER
   and severity:
   GL_DEBUG_SEVERITY_HIGH, GL_DEBUG_SEVERITY_MEDIUM,
   GL_DEBUG_SEVERITY_LOW, GL_DEBUG_SEVERITY_NOTIFICATION */
   // add the message text and eventually add userdata
   // log/output
}

With this one receives meaningful messages on error conditions. Checking glError is not necessary any more and parameterized one can run with a debug context and without, saving a bit of performance.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.