glCreateShader失败并返回0

时间:2014-11-02 11:43:19

标签: c++ opengl sdl shader glew

我遇到了glCreateShaders的问题。它总是返回0.我正在使用Glew和SDL,每当我运行程序时,它都说:

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:我是初学者,所以请不要用一些先进的东西回答:D

编辑1: 02/11/2014(11/02/2014美国人) 我从我正在使用的教程中下载了源代码并且它正在运行。所以我的代码就有了。当我发现问题时,我会编辑帖子。

1 个答案:

答案 0 :(得分:2)

删除文件 GLSLProgram.cpp 中的分号:

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

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