2012-09-08 21 views
13

Ich sollte die neueste Version von Glew und Glut haben, damit sollte nicht das Problem sein. Alles sollte verlinkt werden, und ich verwende MS Visual Studio 2010. Mein Programm kompiliert, aber wenn ich zu glCreateShader (GL_FRAGMENT_SHADER) bekomme, zeigt es einen Fehler: "0xC0000005: Zugriffsverletzung."glCreateShader stürzt ab

mein Programm:

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

Antwort

37

Sie haben GLEW zu initialisieren, bevor Sie es verwenden können:

GLenum err = glewInit();

+0

Dank Ben. Es funktionierte. Allerdings habe ich eine andere Variante verwendet, die ich aus Gründen der Übersichtlichkeit hier als Antwort schreibe. – sinner

2

Es gibt eine andere Situation ist, wenn dies geschehen kann und die Bedingungen sind bei weitem nicht offensichtlich. Wenn Sie sich entscheiden GLFW UND glew in Ihrer Anwendung zu verwenden, können Sie auch in glCreateShader Ende() ACCESS_VIOLATION, wenn Sie schrieb:

Wenn Sie diese Zeile zu

ändern
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE); 

die ACCESS_VIOLATION durch auf den NULL-Funktionszeiger glCreateShader() ist weg.

Fragen Sie mich nicht, wie die beiden Bibliotheken glechten und sich gegenseitig stören ... Voodoo-Alarm!

+2

Ich löste dieses Problem, indem ich glewInit() nach glfwMakeContextCurrent() aufruft. – jimvonmoon

+0

Zusätzlich zu @jimvonmoons Vorschlag muss das Fenster, zu dem der Shader gehört, zu diesem Zeitpunkt der Shader-Erstellung aktuell sein. Das war mein Fehler. – scones

+0

Danke, Sie haben mich vor 10 Tagen Debugging gerettet – Matth

0

Hier ist meine Variante, die eine Antwort von @ BenRujil ist die Antwort oben.

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

Wenn Sie mit GLFW und GLEW/GLXW, für die Adresse eine Zugriffsverletzung bekommen 0 kann passieren, wenn Sie GLEW/GLXW vor Erstellung eines gültigen openGL Zusammenhang mit GLFW zu initialisieren sind versuchen:

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; 
} 

Aufruf glxwInit() vor Kontext Schaffung abholt, was Standardkontext eingestellt und kann die Zugriffsverletzung auslösen (möglicherweise müssen zur Laufzeit abgeholt werden).