2012-09-08 425 views
13

我應該有Glew和Glut的最新版本,所以不應該是問題。一切都應該鏈接,我使用微軟visual studio 2010.我的程序編譯,但是當我到達glCreateShader(GL_FRAGMENT_SHADER)它顯示錯誤:「0xC0000005:訪問衝突。」glCreateShader崩潰了

我的程序:

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

回答

37

您必須初始化GLEW之前,你可以使用它:

GLenum err = glewInit();

+0

謝謝本。有效。不過,爲了清楚起見,我使用了另一個變體,我將其作爲答案發布。 – sinner

2

還有時會發生這種情況,條件還遠遠沒有明顯的另一種情況。 如果你決定使用GLFW和GLEW在你的應用程序,也可以結束在glCreateShader()ACCESS_VIOLATION,如果你寫:

如果更改此行

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE); 

到期ACCESS_VIOLATION到NULL函數指針glCreateShader()消失了。

不要問我,兩個圖書館如何與glfw互相干擾... voodoo警報!

+2

我通過在glfwMakeContextCurrent()之後調用glewInit()來解決該問題。 – jimvonmoon

+0

除了@jimvonmoon的建議,着色器所屬的窗口必須是當前着色器創建時的當前窗口。這是我的錯誤。 – scones

+0

謝謝,您從10天的調試中拯救了我 – Matth

0

這是我的變體,它是@ BenRujil上面的答案的後續。

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

如果您使用GLFW GLEW/GLXW,得到一個訪問衝突的地址0可以發生,如果你試圖初始化GLEW/GLXW 創建與GLFW一個有效的OpenGL上下文之前:

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

上下文創建之前調用glxwInit()將拿起任何默認情況下被設置,並且可以觸發訪問衝突(可能需要在運行時被拾起)。