收到“错误编译:0:1(1):错误:语法错误,意外的$ end” C ++,GLSL,着色器文件

时间:2018-09-02 04:23:25

标签: c++ opengl glsl

这是我的shader.cpp。在我的AddShader函数中,如果将顶点和片段着色器硬编码为带有末尾的'\n''\'的字符串,则可以很好地传递顶点着色器和片段着色器。但是,当我尝试从文件加载它们时,标题中出现错误。我读过与我的问题相似的标题,但它们没有帮助。

#include "shader.h"

Shader::Shader()
{
  m_shaderProg = 0;
}

Shader::~Shader()
{
  for (std::vector<GLuint>::iterator it = m_shaderObjList.begin() ; it != m_shaderObjList.end() ; it++)
  {
    glDeleteShader(*it);
  }

  if (m_shaderProg != 0)
  {
    glDeleteProgram(m_shaderProg);
    m_shaderProg = 0;
  }
}

bool Shader::Initialize()
{
  m_shaderProg = glCreateProgram();

  if (m_shaderProg == 0)
  {
    std::cerr << "Error creating shader program\n";
    return false;
  }

  return true;
}

std::string Shader::readFile(GLenum ShaderType)
{
  std::ifstream finV("shader.vert");
  std::ifstream finF("shader.frag");
  std::string content;
  if(ShaderType == GL_VERTEX_SHADER)
  {
    // If the file was opened successfully, continue
    if(finV)
    {
      while(finV)
      {
        std::cout << content << std::endl;
        getline(finV, content);
      }
    }
  }
  else if (ShaderType == GL_FRAGMENT_SHADER)
  {
    if(finF)
    {
      while(finF)
      {
        std::cout << content << std::endl;
        getline(finF, content);
      }
    }
  }
  finV.close();
  finF.close();
  return content;
}

// Use this method to add shaders to the program. When finished - call finalize()
bool Shader::AddShader(GLenum ShaderType)
{

  if(ShaderType == GL_VERTEX_SHADER)
  {
    m_s = readFile(GL_VERTEX_SHADER);
  }
  else if(ShaderType == GL_FRAGMENT_SHADER)
  {
    m_s = readFile(GL_FRAGMENT_SHADER);
  }

  GLuint ShaderObj = glCreateShader(ShaderType);

  if (ShaderObj == 0)
  {
    std::cerr << "Error creating shader type " << ShaderType << std::endl;
    return false;
  }

  // Save the shader object - will be deleted in the destructor
  m_shaderObjList.push_back(ShaderObj);

  const GLchar* p[1];
  p[0] = m_s.c_str();
  GLint Lengths[1] = { (GLint)m_s.size() };

  glShaderSource(ShaderObj, 1, p, Lengths);

  glCompileShader(ShaderObj);

  GLint success;
  glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success);

  if (!success)
  {
    GLchar InfoLog[1024];
    glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog);
    std::cerr << "Error compiling: " << InfoLog << std::endl;
    return false;
  }

  glAttachShader(m_shaderProg, ShaderObj);

  return true;
}


// After all the shaders have been added to the program call this function
// to link and validate the program.
bool Shader::Finalize()
{
  GLint Success = 0;
  GLchar ErrorLog[1024] = { 0 };

  glLinkProgram(m_shaderProg);

  glGetProgramiv(m_shaderProg, GL_LINK_STATUS, &Success);
  if (Success == 0)
  {
    glGetProgramInfoLog(m_shaderProg, sizeof(ErrorLog), NULL, ErrorLog);
    std::cerr << "Error linking shader program: " << ErrorLog << std::endl;
    return false;
  }

  glValidateProgram(m_shaderProg);
  glGetProgramiv(m_shaderProg, GL_VALIDATE_STATUS, &Success);
  if (!Success)
  {
    glGetProgramInfoLog(m_shaderProg, sizeof(ErrorLog), NULL, ErrorLog);
    std::cerr << "Invalid shader program: " << ErrorLog << std::endl;
    return false;
  }

  // Delete the intermediate shader objects that have been added to the program
  for (std::vector<GLuint>::iterator it = m_shaderObjList.begin(); it != m_shaderObjList.end(); it++)
  {
    glDeleteShader(*it);
  }

  m_shaderObjList.clear();

  return true;
}


void Shader::Enable()
{
    glUseProgram(m_shaderProg);
}


GLint Shader::GetUniformLocation(const char* pUniformName)
{
    GLuint Location = glGetUniformLocation(m_shaderProg, pUniformName);

    if (Location == INVALID_UNIFORM_LOCATION) {
        fprintf(stderr, "Warning! Unable to get the location of uniform '%s'\n", pUniformName);
    }

    return Location;
}

分别是我的顶点着色器和片段着色器。

#version 330

layout (location = 0) in vec3 v_position;
layout (location = 1) in vec3 v_color;

smooth out vec3 color;

uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;

void main(void)
{
  vec4 v = vec4(v_position, 1.0);
  gl_Position = (projectionMatrix * viewMatrix * modelMatrix) * v;
  color = v_color;
}

#version 330

smooth in vec3 color;

out vec4 frag_color;

void main(void)
{
  frag_color = vec4(color.rgb, 1.0);
}

这也是我的shader.h。

#ifndef SHADER_H
#define SHADER_H

#include <vector>
#include <string>
#include <fstream>

#include "graphics_headers.h"

class Shader
{
  public:
    Shader();
    ~Shader();
    bool Initialize();
    void Enable();
    bool AddShader(GLenum ShaderType);
    bool Finalize();
    GLint GetUniformLocation(const char* pUniformName);
    std::string readFile(GLenum ShaderType);

  private:
    GLuint m_shaderProg;
    std::vector<GLuint> m_shaderObjList;
    std::string m_s;
};

#endif  /* SHADER_H */

这是我的graphics_headers.h要详尽的说明。

#ifndef GRAPHICS_HEADERS_H
#define GRAPHICS_HEADERS_H

#include <iostream>

#define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED

#if defined(__APPLE__) || defined(MACOSX)
  #include <OpenGL/gl3.h>
  #include <OpenGL/GLU.h>
#else //linux as default
  #include <GL/glew.h>
  //#include <GL/glu.h>
#endif

// GLM for matricies
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/rotate_vector.hpp>

#define INVALID_UNIFORM_LOCATION 0x7fffffff

struct Vertex
{
  glm::vec3 vertex;
  glm::vec3 color;

  Vertex(glm::vec3 v, glm::vec3 c): vertex(v), color(c) {}
};

#endif /* GRAPHICS_HEADERS_H */

2 个答案:

答案 0 :(得分:1)

std::getline不会将读取的内容附加到std::stringstd::string的先前内容被新提取的序列替换。

如果要从着色器文件读取整个文本,则可以使用std::istreambuf_iterator

#include <fstream>
#include <iterator> // std::istreambuf_iterator

std::string content;

std::ifstream finV("shader.vert");
if ( finV.is_open() )
    content = std::string(
        std::istreambuf_iterator<char>(finV), std::istreambuf_iterator<char>());

答案 1 :(得分:0)

如果您真的想使用std::getline,这是一个肮脏的小技巧,只需创建缓冲区,然后将其添加到内容中,就像@up写std::getline会重置{{1}的全部内容}对象,并在其中添加新行。

绝对不是最快的解决方案:

std::string

为我工作。