2014-03-05 103 views
5

我正在使用C++和Visual Studio學習OpenGL,當我運行我的程序時,它迅速提示顯示窗口,然後崩潰,導致我到一個斷點處顯示「Unhandled exception at 0x00000000 in OpenGL.exe:0xC000000005:訪問衝突。「C++ OpenGL glCreateProgram在Windows上返回0

這是我的代碼:

#include <iostream> 
#include <string> 
#include <fstream> 

#include <sdl2/SDL.h> 
#include <gl/glew.h> 

GLuint crearShader (const std :: string & texto, GLenum tipo); 
std :: string cargarShader (const std :: string & nombreArchivo); 
void comprobarErrorShader (GLuint shader, GLuint flag, bool esPrograma, const std :: string & mensaje); 

void display() 
{ 
    SDL_Init(SDL_INIT_EVERYTHING); 

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); 
    SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); 
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 

    SDL_Window * ventana = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
    640, 480, SDL_WINDOW_OPENGL); 
    SDL_GLContext contexto = SDL_GL_CreateContext(ventana); 
    GLenum estado = glewInit(); 

    if (estado != GLEW_OK) 
    { 
     std :: cerr << "Fallo al inicializar Glew." << std :: endl; 
     exit(EXIT_FAILURE); 
    } 

    GLuint programa = glCreateProgram(); // <-- Problem goes here. 
    const unsigned int NUM_SHADERS = 2; 
    GLuint shaders[ NUM_SHADERS ]; 
    shaders[0] = crearShader(cargarShader("./shaderBasico.vs"), GL_VERTEX_SHADER); 
    shaders[1] = crearShader(cargarShader("./shaderBasico.fs"), GL_FRAGMENT_SHADER); 
    unsigned int i; 

    for (i = 0; i < NUM_SHADERS; i++) 
    { 
     glAttachShader(programa, shaders[ i ]); 
    } 

    glLinkProgram(programa); 
    comprobarErrorShader(programa, GL_LINK_STATUS, true, "Error: Fallo al vincular el programa: "); 

    glValidateProgram(programa); 
    comprobarErrorShader(programa, GL_VALIDATE_STATUS, true, "Error: El programa es invalido: "); 

    SDL_Event evento; 

    do 
    { 
     glClearColor(0x00, 0x00, 0x00, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT); 
     glUseProgram(programa); 
     SDL_GL_SwapWindow(ventana); 
     SDL_PollEvent(&evento); 
    } 
    while (evento.type != SDL_QUIT) ; 

    for (i = 0; i < NUM_SHADERS; i++) 
    { 
     glDetachShader(programa, shaders[ i ]); 
     glDeleteShader(shaders[ i ]); 
    } 

    glDeleteProgram(programa); 
    SDL_GL_DeleteContext(contexto); 
    SDL_DestroyWindow(ventana); 
    SDL_Quit(); 
} 

GLuint crearShader (const std :: string & texto, GLenum tipo) 
{ 
    GLuint shader = glCreateShader(tipo); 

    if (shader == 0) 
    { 
     std :: cerr << "Error al crear shader." << std :: endl; 
    } 

    const GLchar * shaderSourceStrings[1] = {texto.c_str()}; 
    GLint shaderSourceStringLengths[1] = {texto.length()}; 
    glShaderSource(shader, 1, shaderSourceStrings, shaderSourceStringLengths); 
    glCompileShader(shader); 

    comprobarErrorShader(shader, GL_COMPILE_STATUS, true, "Error: Fallo al vincular el programa: "); 

    return shader; 
} 

std :: string cargarShader (const std :: string & nombreArchivo) 
{ 
    std :: ifstream archivo; 
    archivo.open(nombreArchivo.c_str()); 

    std :: string salida; 
    std :: string linea; 

    if (archivo.is_open()) 
    { 
     while (archivo.good()) 
     { 
      getline(archivo, linea); 
      salida.append(linea + "\n"); 
     } 
    } 
    else 
    { 
     std :: cerr << "Error, no se pudo cargar un shader." << std :: endl; 
    } 

    return salida; 
} 

void comprobarErrorShader (GLuint shader, GLuint flag, bool esPrograma, const std :: string & mensaje) 
{ 
    GLint exito = 0; 
    GLchar error[1024] = { 0 }; 

    if (esPrograma) 
    { 
     glGetProgramiv(shader, flag, &exito); 
    } 
    else 
    { 
     glGetShaderiv(shader, flag, &exito); 
    } 

    if (exito == GL_FALSE) 
    { 
     if (esPrograma) 
     { 
      glGetProgramInfoLog(shader, sizeof error, NULL, error); 
     } 
     else 
     { 
      glGetShaderInfoLog(shader, sizeof error, NULL, error); 
     } 

     std :: cerr << mensaje << ": '" << error << "'" << std :: endl; 
    } 
} 

int main (int argc, char * argv[]) 
{ 
    display(); 

    return 0; 
} 

正如你可以看到我創建的程序,仍然給我的錯誤,任何想法初始化之前GLEW?

+1

'glCreateProgram()'NULL?什麼'glGetString(GL_VERSION)'返回?你正在做一些不尋常的事情,比如在虛擬機或遠程桌面上運行嗎?如果刪除所有的'SDL_GL_SetAttribute()'調用,有什麼改變? – genpfault

+0

你好,glGetString(GL_VERSION)返回1.4.0 - 生成8.14.10.2364,我試着通過comenting所有的SDL_GL_SetAttribute,仍然給我例外,通過我無法確定glCreateProgram因爲崩潰返回的值, m沒有在遠程桌面上運行。 –

回答

3

glGetString(GL_VERSION)回報1.4.0 - 構建8.14.10.2364

那麼你去那裏,glCreateProgram()沒有核心在OpenGL 1.4。

GLEW很可能將glCreateProgram()設置爲NULL。

Check如果你的GL實現支持ARB_vertex_shaderARB_fragment_shader,並ARB_shader_objects和使用這些功能的ARB代替。

如果這些擴展不是支持,那麼你在着色器前面是SOL,除非你想使用像Mesa這樣的軟件光柵化器。

+0

你是正確的伴侶,我的視頻卡不會允許我升級我的OpenGL版本,所以它不支持glCreateProgram,但是它對於ARB_vertex_shader和ARB_fragment_shader(我簽出了),所以我相信這是我的出路,謝謝爲你的時間。 –

3

我有這個相同的問題。我在我的macbook上通過rdp連接運行visual studio。當我在運行連接的PC上運行它時,它工作正常。 `glCreateProgram()`NULL?