glCreateShader is crashing
Asked Answered
B

5

25

I should have the newest version of Glew and Glut so that shouldn't be the problem. Everything should be linked, and I'm using MS visual studio 2010. My program compiles but when I get to glCreateShader(GL_FRAGMENT_SHADER) it show an error: "0xC0000005: Access violation."

my program:

#include <GL\glew.h>
#include <GL\glut.h>
#include <stdio.h>
#include <stdlib.h>

GLuint program;

static char* readShaderSource(const char * shaderFile)
{
    FILE* fp = fopen(shaderFile, "r");
    char* buf;
    long size;

    if (fp == NULL) return NULL; 
    fseek(fp, 0L, SEEK_END);//go to end
    size = ftell(fp);       //get size
    fseek(fp, 0L, SEEK_SET);//go to begining

    buf = (char*) malloc((size +1) * sizeof(char));
    fread(buf, 1, size, fp);
    buf[size] = NULL;
    fclose(fp);
    return buf;
}

static void initShader(const GLchar * fsFile)
{
    GLint status;
    GLchar * fSource;
    GLuint fShader;
    GLuint fShader2;

    //read file
    fSource = readShaderSource(fsFile);
    if (fSource == NULL)
    {
        printf("Fail to load file");
        exit(EXIT_FAILURE);
    }

    //Create program and shader object
    fShader2 = glCreateShader(GL_VERTEX_SHADER);
    fShader = glCreateShader(GL_FRAGMENT_SHADER);
    program = glCreateProgram();

    //Attach shaders to program
    glAttachShader(program, fShader);

    //read shaders
    glShaderSource(fShader, 1, (const GLchar**) &fSource, NULL);

    //compile fragment shader
    glCompileShader(fShader);

    //error check
    glGetShaderiv(fShader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE)
    {
        printf("Failed to compile the fragment shader.");
        exit(EXIT_FAILURE);
    }

    //link and error check
    glLinkProgram(program);
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status == GL_FALSE)
    {
        printf("program error");
        exit(EXIT_FAILURE);
    }

    //use program object
    glUseProgram(program);

    //set up uniform parameter
    //skipped for now
}

int main(int argc, char ** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500,500);
    glutCreateWindow("Matrix Fractal");
    glClearColor(1.0, 1.0, 1.0, 1.0);
    gluOrtho2D(0.0,0.0,(GLfloat) 500, (GLfloat) 500);

    glutDisplayFunc(draw);
    glutReshapeFunc(reshape);

    initShader("fsFractal.glsl");

    glutMainLoop();
}
Boracic answered 8/9, 2012 at 8:0 Comment(0)
H
59

You have to initialize GLEW before you can use it:

GLenum err = glewInit();

Hefter answered 8/9, 2012 at 8:9 Comment(1)
Thanks Ben. It worked. However I used another variant which I am posting as an answer below for clarity sake.Nonresistance
Z
6

There is another situation when this can happen and the conditions are far from obvious. If you decide to use glfw AND glew in your application, you can also end in glCreateShader() ACCESS_VIOLATION, if you wrote:

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

If you change this line to

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

the ACCESS_VIOLATION due to the NULL function pointer glCreateShader() is gone.

Do not ask me, how the two libraries glew and glfw interfere with each other... voodoo alert!

Zymogenesis answered 8/5, 2014 at 12:31 Comment(3)
I solved that problem by calling glewInit() after glfwMakeContextCurrent().Incontrovertible
In addition to @Incontrovertible 's suggestion, the window to which the shader belongs, has to be current at that time of the shader creation. This was my mistake.Sherleysherline
Thanks, you saved me from 10 days of debuggingNeoplasm
N
4

Here is my variant which is a follow up from @BenRujil's answer above.

   glewExperimental = GL_TRUE;
    if(glewInit() != GLEW_OK)
        throw std::runtime_error("glewInit failed");
Nonresistance answered 5/11, 2014 at 20:24 Comment(0)
K
3

If you're using GLFW and GLEW/GLXW, getting an access violation for address 0 can happen if you're trying to initialize GLEW/GLXW before creating a valid openGL context with GLFW:

if (!glfwInit()) {
  std::cerr << "GL initialization failed" << std::endl;
  return 1;
}
// Setup the openGL profile you need - we're going with a 4.3 core profile
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Context creation happens in the line below
GLFWwindow *window = glfwCreateWindow(800, 600, "text", NULL, NULL);
if (!window) {
  std::cerr << "Window or GL initialization failed";
  glfwTerminate();
  return 1;
}
glfwMakeContextCurrent(window);
if (glxwInit()) { // Now it's a good time to initialize Xtension wranglers
  std::cerr << "Failed to initialize GLXW" << std::endl;
  return 1;
}

Calling glxwInit() before context creation will pick up whatever default context is set and can trigger the access violation (might need to be picked up at runtime).

Kramatorsk answered 28/11, 2016 at 10:28 Comment(0)
S
2

If it's a problem with GLFW, you can ask them for an error message before they crash your program.

Windows example:

Create a callback function:

#include <windows.h>
void glfw_onError(int error, const char* description)
{
    // print message in Windows popup dialog box
    MessageBox(NULL, description, "GLFW error", MB_OK);
}

and set it at the very beginning of your code.

glfwSetErrorCallback(glfw_onError);

I did that and got "The GLFW library is not initialized." Turns out my GLFW library wasn't initialized. Turns out Ben's answer was right. I just had glfwInit() in an assert like this: assert(glfwInit()); so it was being stripped when I compiled my program for Release.

Stegodon answered 25/11, 2019 at 12:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.