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

问题描述 投票:1回答:2

这是我的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 */
c++ opengl glsl
2个回答
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>());

0
投票

如果你真的想要使用std::getline,这里是一个小脏兮兮的,只需制作缓冲区然后将其添加到内容中,就像@up写的std::getline重置std::string对象的全部内容并将新行放入其中。

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

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::string buffer = "";
                getline(finV, buffer);
                content += buffer + "\n";
            }
        }
    }
    else if (ShaderType == GL_FRAGMENT_SHADER)
    {
        if (finF)
        {
            while (finF)
            {
                std::string buffer = "";
                getline(finF, buffer);
                content += buffer + "\n";
            }
        }
    }
    finV.close();
    finF.close();
    std::cout << content << std::endl;

    return content;
}

适合我。

© www.soinside.com 2019 - 2024. All rights reserved.