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, 2020 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, 2020 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, 2020 at 6:22

1 Answer 1

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .