2014-11-02 196 views
2

我遇到了glCreateShaders的问题。它总是返回0。我使用GLEW与SDL,每当我运行程序,它说:glCreateShader失败并返回0

0(1) : error C0000: syntax error, unexpected '}' at token "}" 

Shader Shaders/colorShading.vert failed to compile! 

main.cpp中:

#include <iostream> 
#include "MainGame.h" 

int main(int argc, char** argv) 
{ 
    MainGame maingame; 
    maingame.run(); 

    return 0; 
} 

MainGame.h:

//Core -> initializing glew, sdl etc... 
//Just ignore the sprite class 
#pragma once 
#include <SDL/SDL.h> 
#include <GL/glew.h> 
#include <iostream> 
#include <string> 

#include "Errors.h" 
#include "GLSLProgram.h" 


enum class GameState {PLAY, EXIT}; 

#include "Sprite.h" 

class MainGame 
{ 
public: 
    MainGame(void); 
    ~MainGame(void); 

    void run(); 
private: 
    void initSystems(); 
    void initShaders(); 
    void gameLoop(); 
    void processInput(); 
    void drawGame(); 

    SDL_Window* _window; 
    int _screenWidth; 
    int _screenHeight; 
    GameState _gameState; 

    Sprite _sprite; 
    GLSLProgram _colorProgram; 
}; 

MainGame.cpp:

#include "MainGame.h" 

MainGame::MainGame(void) 
{ 
    _window = nullptr; 
    _screenWidth = 1024; 
    _screenHeight = 700; 
    _gameState = GameState::PLAY; 
} 

MainGame::~MainGame(void) 
{ 
} 

void MainGame::run() 
{ 
    initSystems(); 
    _sprite.init(-1.0f, -1.0f, 1.0f, 1.0f); 
    gameLoop(); 
} 

void MainGame::initSystems() 
{ 
    //Initialize SDL 
    SDL_Init(SDL_INIT_EVERYTHING); 

    _window = SDL_CreateWindow("Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, _screenWidth, _screenHeight, SDL_WINDOW_OPENGL); 
    if (_window == nullptr) 
    { 
     fatalError("SDL Window could not be created!"); 
    } 

    SDL_GLContext glContext = SDL_GL_CreateContext(_window); 
    if (glContext == nullptr) 
     fatalError("SDL_GL context could not be created!"); 

    GLenum error = glewInit(); 
    if (error != GLEW_OK) 
     fatalError("Could not initialize glew!"); 

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 

    glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 

    initShaders(); 
} 

void MainGame::initShaders() 
{ 
    _colorProgram.compileShaders("Shaders/colorShading.vert", "Shaders/colorShading.frag"); 
    _colorProgram.addAttribute("vertexPosition"); 
    _colorProgram.linkShaders(); 
} 

void MainGame::gameLoop() 
{ 
    while (_gameState != GameState::EXIT) 
    { 
     processInput(); 
     drawGame(); 
    } 
} 

void MainGame::processInput() 
{ 
    SDL_Event evnt; 
    while (SDL_PollEvent(&evnt)) 
    { 
     switch (evnt.type) 
     { 
     case SDL_QUIT: 
      _gameState = GameState::EXIT; 
      break; 
     case SDL_MOUSEMOTION: 
      std::cout << "New Coords: " << evnt.motion.x << " " << evnt.motion.y << std::endl; 
      break; 
     } 
    } 

} 

void MainGame::drawGame() 
{ 
    glClearDepth(1.0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    _colorProgram.use(); 

    _sprite.draw(); 

    _colorProgram.unUse(); 

    SDL_GL_SwapWindow(_window); 
} 

GLSLProgram.h:

//Used for 
#pragma once 
#include <string> 
#include <GL/glew.h> 
//#include <SDL/SDL.h> 
#include "Errors.h" 


class GLSLProgram 
{ 
public: 
    GLSLProgram(); 
    ~GLSLProgram(); 

    void compileShaders(const std::string& vertextShaderFilePath, const std::string& fragmentShaderFilePath); 

    void linkShaders(); 

    void addAttribute(const std::string&); 

    void use(); 
    void unUse(); 
private: 
    int _numAttributes; 
    void _compileShader(const std::string&, GLuint); 

    GLuint _programID; 

    GLuint _vertexShaderID; 
    GLuint _fragmentShaderID; 
}; 

GLSLProgram.cpp:

//Used for compiling shaders 
#include "GLSLProgram.h" 
#include <fstream> 
#include <vector> 


GLSLProgram::GLSLProgram() : _numAttributes(0), _programID(0), _vertexShaderID(0), _fragmentShaderID(0) 
{ 
} 


GLSLProgram::~GLSLProgram() 
{ 
} 

void GLSLProgram::compileShaders(const std::string& vertexShaderFilePath, const std::string& fragmentShaderFilePath) 
{ 
    _vertexShaderID = glCreateShader(GL_VERTEX_SHADER); 
    if (_vertexShaderID == 0) 
    { 
     fatalError("Vertex shader failed to be created!"); 
     SDL_Quit(); 
    } 

    _fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); 
    if (_fragmentShaderID == 0) 
    { 
     fatalError("Fragment shader failed to be created!"); 
     SDL_Quit(); 
    } 

    _compileShader(vertexShaderFilePath, _vertexShaderID); 
    _compileShader(fragmentShaderFilePath, _fragmentShaderID); 

} 

void GLSLProgram::addAttribute(const std::string& attributeName) 
{ 
    glBindAttribLocation(_programID, _numAttributes++, attributeName.c_str()); 
} 

void GLSLProgram::use() 
{ 
    glUseProgram(_programID); 
    for (int x = 0; x < _numAttributes; x++) 
    { 
     glEnableVertexAttribArray(x); 
    } 
} 

void GLSLProgram::unUse() 
{ 
    glUseProgram(0); 
    for (int x = 0; x < _numAttributes; x++) 
    { 
     glDisableVertexAttribArray(x); 
    } 
} 

void GLSLProgram::linkShaders() 
{ 
    //Vertex and fragment shaders are successfully compiled. 
    //Now time to link them together into a program. 
    //Get a program object. 
    _programID = glCreateProgram(); 

    //Attach our shaders to our program 
    glAttachShader(_programID, _vertexShaderID); 
    glAttachShader(_programID, _fragmentShaderID); 

    //Link our program 
    glLinkProgram(_programID); 

    //Note the different functions here: glGetProgram* instead of glGetShader*. 
    GLint isLinked = 0; 
    glGetProgramiv(_programID, GL_LINK_STATUS, (int *)&isLinked); 
    if (isLinked == GL_FALSE) 
    { 
     GLint maxLength = 0; 
     glGetProgramiv(_programID, GL_INFO_LOG_LENGTH, &maxLength); 

     //The maxLength includes the NULL character 
     std::vector<char> infoLog(maxLength); 
     glGetProgramInfoLog(_programID, maxLength, &maxLength, &infoLog[0]); 

     //We don't need the program anymore. 
     glDeleteProgram(_programID); 
     //Don't leak shaders either. 
     glDeleteShader(_vertexShaderID); 
     glDeleteShader(_fragmentShaderID); 

     printf("%s\n", &(infoLog[0])); 
     fatalError("Shaders failed to link!"); 
    } 

    //Always detach shaders after a successful link. 
    glDetachShader(_programID, _vertexShaderID); 
    glDetachShader(_programID, _fragmentShaderID); 
    glDeleteProgram(_programID); 
    glDeleteShader(_vertexShaderID); 
    glDeleteShader(_fragmentShaderID); 
} 

void GLSLProgram::_compileShader(const std::string &filePath, GLuint id) 
{ 
    std::ifstream vertexFile(filePath); 
    if (vertexFile.fail()) 
    { 
     perror(filePath.c_str()); 
     fatalError("Failed to open " + filePath); 
    } 

    std::string fileContents; 
    std::string line; 
    while (std::getline(vertexFile, line)); 
    { 
     fileContents += line + "\n"; 
    } 

    vertexFile.close(); 

    const char *contentsPtr = fileContents.c_str(); 
    glShaderSource(id, 1, &contentsPtr, nullptr); 
    glCompileShader(id); 

    GLint isCompiled = 0; 
    glGetShaderiv(id, GL_COMPILE_STATUS, &isCompiled); 
    if (isCompiled == GL_FALSE) 
    { 
     GLint maxLength = 0; 
     glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength); 

     //The maxLength includes the NULL character 
     std::vector<char> errorLog(maxLength); 
     glGetShaderInfoLog(id, maxLength, &maxLength, &errorLog[0]); 

     //Provide the infolog in whatever manor you deem best. 
     //Exit with failure. 
     glDeleteShader(id); //Don't leak the shader. 

     printf("%s\n", &(errorLog[0])); 
     fatalError("Shader" + filePath + "failed to compile!"); 
    } 
} 

顶点着色器:

#version 130 
//The vertex shader operates on each vertex 

//input data from the VBO. Each vertex is 2 floats 
in vec2 vertexPosition; 

void main() 
{ 
    //Set the x,y position on the screen 
    gl_Position.xy = vertexPosition; 
    //the z position is zero since we are in 2D 
    gl_Position.z = 0.0; 

    //Indicate that the coordinates are normalized 
    gl_Position.w = 1.0; 
} 

和片段着色器:

#version 130 
//The fragment shader operates on each pixel in a given polygon 

//This is the 3 component float vector that gets outputted to the screen 
//for each pixel. 
out vec3 color; 

void main() { 
    //Just hardcode the color to red 
    color = vec3(1.0, 0.0, 1.0); 
} 

我没有任何想法,为什么它正在发生。 :(

PS:我跟GLEW初学者所以请不要用一些东西提前答案:d

编辑1: 2014年2月11日(2014年11月2日对美国人) 我下载从我所用的教程中的源代码,这是工作。所以在网上有什么东西与我的代码。我将编辑后,当我发现这个问题。

+0

你确定glCreateShader返回0吗?对我来说,看起来好像你的着色器不能编译。 – BDL 2014-11-02 12:00:22

+0

在调用glShaderSource之前尝试输出着色器源代码。 – Ben 2014-11-02 12:06:32

+0

@BDL我认为这将是问题 – BBPP20 2014-11-02 12:15:21

回答

2

删除分号文件GLSLProgram.cpp

while (std::getline(vertexFile, line)); 

您将通过该文件,然后添加到空字符串fileContents着色器代码的最后一行,即'}'。

+0

这实际上有效!非常感谢你! – BBPP20 2014-11-02 15:48:24

+0

哈哈,哦,伙计。这很简单。 – Ben 2014-11-03 00:20:46

+0

但为什么在整个着色器中输出fileContents? – Ben 2014-11-03 00:29:42