2012-09-08 13 views
13

Dovrei avere la versione più recente di Glew e Glut in modo che non dovrebbe essere il problema. Tutto dovrebbe essere collegato, e sto usando MS Visual Studio 2010. Il mio programma compila ma quando arrivo a glCreateShader (GL_FRAGMENT_SHADER) mostra un errore: "0xC0000005: violazione di accesso."glCreateShader si blocca

mio programma:

#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(); 
} 

risposta

37

Dovete inizializzare GLEW prima di poterlo utilizzare è:

GLenum err = glewInit();

+0

Grazie Ben. Ha funzionato. Comunque ho usato un'altra variante che sto postando come risposta per chiarezza. – sinner

2

C'è un'altra situazione in cui questo può accadere e le condizioni sono tutt'altro che scontato. Se si decide di utilizzare glfw E Glew nella propria applicazione, si può anche finire in glCreateShader() ACCESS_VIOLATION, se hai scritto:

Se si modifica questa linea per

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE); 

l'ACCESS_VIOLATION dovuta il puntatore della funzione NULL glCreateShader() è scomparso.

Non chiedetemi, come le due librerie glew e glfw interferiscono l'una con l'altra ... allarme voodoo!

+2

Ho risolto il problema chiamando glewInit() dopo glfwMakeContextCurrent(). – jimvonmoon

+0

Oltre al suggerimento di @jimvonmoon, la finestra a cui appartiene lo shader deve essere corrente in quel momento della creazione dello shader. Questo è stato un mio errore. – scones

+0

Grazie, mi hai salvato da 10 giorni di debug – Matth

0

Ecco la mia variante che è un seguito della risposta di @ BenRujil sopra.

glewExperimental = GL_TRUE; 
    if(glewInit() != GLEW_OK) 
     throw std::runtime_error("glewInit failed"); 
0

Se stai usando GLFW e GLEW/GLXW, ottenendo una violazione di accesso per l'indirizzo 0 può accadere se si sta cercando di inizializzare GLEW/GLXW prima creare un contesto OpenGL valido 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() prima della creazione contesto prenderà qualsiasi contesto di default è impostato e può innescare la violazione di accesso (potrebbe aver bisogno di essere prelevati in fase di esecuzione).