由于非Ascii字符,顶点着色器无法编译? [英] Vertex shader not compiling due to a non-Ascii character?

查看:120
本文介绍了由于非Ascii字符,顶点着色器无法编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我开始使用带有glew和GLFW的OpenGL创建游戏引擎,并且在开始使用着色器时几乎立即遇到了问题:

So I started using OpenGL with glew and GLFW to create a game engine, and I almost immediately ran into a problem when starting working with shaders:

它们未被使用,或者如果被使用,则没有任何作用.

They are not being used or have no effect whatsoever if they are being used.

我一直在用大量其他示例检查我的代码,并且它们都匹配,没有什么看起来不合适,并且我开始用尽了所有的想法和耐心(我一直在试图找出为什么要使用现在).

I have been checking my code with plenty of other examples, and they all match up, nothing looks out of place, and I am starting to run out of ideas and patience (I have been trying to figure out why for nearly a month now) with this.

我的主要核心代码在这里:

My main core code is here:

  #include "headers/Default.hpp"

  //Window width and height variables
  int windowWidth = 800;
  int windowHeight = 600;
  float Aspect = (float)windowWidth / (float)windowHeight;

  //Buffer width and buffer height
  int bufferWidth;
  int bufferHeight;

  double deltaTime;
  double currentTime;
  double newTime;

  void CalculateDelta()
  {
     newTime = glfwGetTime();
     deltaTime = newTime - currentTime;
     currentTime = newTime;
  }

  //A call back function to get the window size
  void UpdateWindowSize(GLFWwindow* window, int width, int height)
  {
     windowWidth = width;
     windowHeight = height;

     Aspect = (float)windowWidth / (float)windowHeight;
  }

  void UpdateFrameBufferSize(GLFWwindow* window, int width, int height)
  {
     bufferWidth = width;
     bufferHeight = height;
  }

  //Starts on startup and creates an window context and starts the rendering loop
  int main()
  {
     //Creates an engine startup log to keep
     CreateStartupLog();

     if (!glewInit())
     {
        WriteStartupLog("ERROR: GLEW failed to start\n");
        return 1;
     }
     else
     {
        WriteStartupLog("INFO: GLEW initiated!\n");
     }

     //If glfw is not initiated for whatever reason we return an error
     if (!glfwInit())
     {
        WriteStartupLog("ERROR: GLFW failed to start\n");
        return 1;
     }
     else
     {
        WriteStartupLog("INFO: GLFW initiated!\n");
     }

     ////////////////////////////////////////////////////////////////
     //                      Window Section                        //
     ////////////////////////////////////////////////////////////////
     //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
     //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
     //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
     glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

     //Gets the primary monitor of the PC and tells OpenGL to use that monitor
     GLFWmonitor* monitor = glfwGetPrimaryMonitor();
     const GLFWvidmode* videoMode = glfwGetVideoMode(monitor);

     //Creates a GLFW window context that we can work with
     GLFWwindow* gameWindow = glfwCreateWindow(windowWidth/*videoMode->width*/, windowHeight/*videoMode->height*/, "FireTech Engine", NULL/*monitor*/, NULL);

     //If the game window is not able to be created, prints an error and terminates the program
     if (!gameWindow)
     {
        WriteStartupLog("ERROR: GLFW could not create a window\n");
        glfwTerminate();
        return 1;
     }
     else
     {
        WriteStartupLog("INFO: GLFW created a window!\n\n");
     }

     //Makes the current context
     glfwMakeContextCurrent(gameWindow);

     //Sets the window callback function for size
     glfwSetWindowSizeCallback(gameWindow, UpdateWindowSize);
     glfwSetFramebufferSizeCallback(gameWindow, UpdateFrameBufferSize);

     //Initiate GLEW
     glewExperimental = GL_TRUE;
     glewInit();

     ////////////////////////////////////////////////////////////////
     //  Functions to set up various systems of the game engine    //
     ////////////////////////////////////////////////////////////////

     //Calls function to create a log file for the game engine
     CreateEngineLog();
     //Calls the function to compile the default shaders
     CompileDefaultShader();
     //Calls the function to get and print out hardware and OpenGL version
     //PrintHardwareInfo();

     ////////////////////////////////////////////////////////////////
     //                        Game Code                           //
     ////////////////////////////////////////////////////////////////
     Sprite testSprite;

     //Rendering loop
     while (!glfwWindowShouldClose(gameWindow))
     {
        CalculateDelta();
        glClearColor(0.3, 0.6, 1.0, 0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        //Viewport and ortho settings
        glViewport(0, 0, windowWidth, windowHeight);
        glOrtho(-1, 1, -1 / Aspect, 1 / Aspect, 0, 1);

        //Draw a sprite
        if (GLFW_PRESS == glfwGetKey(gameWindow, GLFW_KEY_F2))
        {
           testSprite.DebugDraw();
        }
        else
        {
           testSprite.Draw();
        }

        //Draws the stuff we just rendered
        glfwSwapBuffers(gameWindow);
        glLoadIdentity();

        //Polls different events, like input for example
        glfwPollEvents();

        if (GLFW_PRESS == glfwGetKey(gameWindow, GLFW_KEY_F1))
        {
           int fps = GetFPS();
           printf("FPS: ");
           printf("%d\n", fps);

           printf("Frequency: ");
           printf("%f\n", 1/double(fps));
        }

        if (GLFW_PRESS == glfwGetKey(gameWindow, GLFW_KEY_ESCAPE))
        {
           glfwSetWindowShouldClose(gameWindow, 1);
        }
     }

     glfwTerminate();
     WriteEngineLog("PROGRAM EXITED: Window closed");
     return 0;
  }

这是shader.cpp代码:

Here is the shader.cpp code:

        #include "../headers/Default.hpp"

  string ReadShaderFile(char* path)
  {
     ifstream shaderFile;
     shaderFile.open(path, std::ifstream::in);
     string output;

     if (shaderFile.is_open())
     {
        printf("Opened shader file located at: \"%s\"\n", path);

        while (!shaderFile.eof())
        {
           output += shaderFile.get();
        }

        printf("Successfully read shader file located at: \"%s\"\n", path);
     }
     else
     {
        WriteEngineLog("ERROR: Could not read shader file!\n");
     }

     shaderFile.close();
     return output;
  }

  Shader::Shader()
  {
     WriteEngineLog("WARNING: There was no path to any GLSL Shader files\n");
  }

  Shader::Shader(char* VertexShaderPathIn, char* FragmentShaderPathIn)
  {
     string vertexShaderString = ReadShaderFile(VertexShaderPathIn);
     string fragmentShaderString = ReadShaderFile(FragmentShaderPathIn);

     //Prints out the string to show the shader's code
     printf("\n%s\n", vertexShaderString.c_str());
     printf("\n%s\n", fragmentShaderString.c_str());

     //Creates the GLchars needed to input the shader code
     const GLchar* vertex_shader = vertexShaderString.c_str();
     const GLchar* fragment_shader = fragmentShaderString.c_str();

     //Creates a vertex shader and compiles it
     GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
     WriteEngineLog("Blank vertex shader created\n");
     glShaderSource(vertexShader, 1, &vertex_shader, NULL);
     WriteEngineLog("Vertex shader given source\n");
     glCompileShader(vertexShader);

     //Compilation error checking begions here
     GLint isVertexCompiled = 0;
     glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isVertexCompiled);
     if (isVertexCompiled == GL_FALSE)
     {
        //Gets the length of the log
        GLint maxLength = 0;
        glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);

        //Creates and writes the log to the errorLog
        GLchar* errorLog = (GLchar*)malloc(maxLength);
        glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &errorLog[0]);

        //Writes to the engine log with the shader error
        WriteEngineLog("ERROR: Vertex shader failed to compile!\n");
        printf("%s\n", (char*)errorLog);

        //Frees the errorLog allocation
        free(errorLog);

        //Deletes the shader so it doesn't leak
        glDeleteShader(vertexShader);

        WriteEngineLog("ERROR: Aborting shader creation.\n");
        return;
     }
     //Writes in the engine log to report successful compilation
     WriteEngineLog("Vertex shader successfully compiled!\n");

     //Creates a fragment shader
     GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
     WriteEngineLog("Blank fragment shader created\n");
     glShaderSource(fragmentShader, 1, &fragment_shader, NULL);
     WriteEngineLog("Fragment shader given source\n");
     glCompileShader(fragmentShader);

     //Compilation error checking begions here
     GLint isFragmentCompiled = 0;
     glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isFragmentCompiled);
     if (isFragmentCompiled == GL_FALSE)
     {
        //Gets the length of the log
        GLint maxLength = 0;
        glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);

        //Creates and writes the log to the errorLog
        GLchar* errorLog = (GLchar*)malloc(maxLength);
        glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &errorLog[0]);

        WriteEngineLog("ERROR: Fragment shader failed to compile\n");
        printf("%s\n", (char*)errorLog);

        //Frees the errorLog allocation
        free(errorLog);

        //Deletes the shader so it doesn't leak
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);

        WriteEngineLog("ERROR: Aborting shader creation.\n");
        return;
     }
     //Writes in the engine log to report successful compilation
     WriteEngineLog("Fragment shader successfully compiled!\n");

     //Creates the final shader product
     this->Program = glCreateProgram();
     WriteEngineLog("Blank shader created\n");
     glAttachShader(this->Program, vertexShader);
     WriteEngineLog("Attatched Vertex shader to the shader\n");
     glAttachShader(this->Program, fragmentShader);
     WriteEngineLog("Attatched Fragment shader to the shader\n");
     glLinkProgram(this->Program);

     /*GLint isLinked = 0;
     glGetProgramiv(this->Program, GL_LINK_STATUS, (int*)&isLinked);
     if (isLinked == GL_FALSE)
     {
        //Gets the lngth of the shader info log
        GLint maxLength = 0;
        glGetProgramInfolog(ShaderOut, GL_INFO_LOG_LENGTH, &maxLength);

        //Gets and puts the actual log into a GLchar
        std::vector<GLchar> infoLog(maxLength);
        glGetProgramInfoLog(ShaderOut, maxLength, &maxLength, &infoLog[0]);

        //Deletes programs and shaders so they don't leak
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);

        WriteEngineLog((string)infoLog);

        return;
     }*/

     WriteEngineLog("Shader linked!\n\n");

     WriteEngineLog("INFO: Shader created!\n");

     glDeleteShader(vertexShader);
     glDeleteShader(fragmentShader);
  }

  void Shader::Use()
  {
     glUseProgram(this->Program);
  }

这是quad.cpp代码:

Here is the quad.cpp code:

  #include "../headers/Default.hpp"

  Quad::Quad()
  {
     position.x = 0;
     position.y = 0;
     scale.x = 1;
     scale.y = 1;

     VertexArray = CreateVertexArray();
  }

  //Quad constructor with one arg
  Quad::Quad(Vector2 Position)
  {
     position = Position;

     VertexArray = CreateVertexArray();
  }

  //Quad constructor with two args
  Quad::Quad(Vector2 Position, Vector2 Scale)
  {
     position = Position;
     scale = Scale;

     VertexArray = CreateVertexArray();
  }

  GLuint Quad::CreateVertexArray()
  {
     GLfloat Vertices[] =
     {
         //VERTICES           //COLORS            //TEXCOORDS
         0.5f,  0.5f, 0.0f,   0.0f, 0.0f, 0.0f,   //1.0f, 1.0f, //Top Right Vertice
         0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   //1.0f, 0.0f, //Top Left Vertice
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f//,   0.0f, 0.0f //Bottom Left Vertice
     };

     GLuint vbo, vao;
     glGenVertexArrays(1, &vao);
     glGenBuffers(1, &vbo);

     glBindVertexArray(vao);

     //Copy vertices into the buffer
     glBindBuffer(GL_ARRAY_BUFFER, vbo);
     glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

     //Attribute Pointers
     //Position attribute
     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
     glEnableVertexAttribArray(0);
     //Color attribute
     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
     glEnableVertexAttribArray(1);

     //Unbinds the VAO
     glBindVertexArray(0);

     return vao;
  }

  //Quad debug drawing function
  void Quad::DebugDraw()
  {
     //Use the default shader
     DefaultShader.Use();

     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
     glBindVertexArray(VertexArray);

     // draw points 0-3 from the currently bound VAO with current in-use shader
     glDrawArrays(GL_TRIANGLES, 0, 3);
     //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //CAUSING A CRASH AT THE MOMENT

     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

     //Unbinds the VAO
     glBindVertexArray(0);
  }

这是sprite.cpp代码:

Here is the sprite.cpp code:

  #include "../headers/Default.hpp"

  Sprite::Sprite()
  {
     position.x = 0;
     position.y = 0;
  }

  Sprite::Sprite(Texture tex)
  {
     defaultTexture = tex;
     currentTexture = tex;
  }

  Sprite::Sprite(Texture tex, Vector2 pos)
  {
     defaultTexture = tex;
     currentTexture = tex;
     position = pos;
  }

  Sprite::Sprite(Texture tex, Vector2 pos, Vector2 Scale)
  {
     defaultTexture = tex;
     currentTexture = tex;
     position = pos;
     scale = Scale;
  }

  void Sprite::Draw()
  {
     //Binds the default shader again
     glBindVertexArray(VertexArray);

     //Use the default shader
     DefaultShader.Use();

     // draw points 0-3 from the currently bound VAO with current in-use shader
     glDrawArrays(GL_TRIANGLES, 0, 3);

     glBindVertexArray(0);
  }

这是我的顶点着色器和片段着色器代码(按顺序):

Here is my vertex shader and fragment shader code (In order):

  //Vertex Shader
  #version 330 core

  layout (location = 0) in vec3 position; // The position variable has attribute position 0
  layout (location = 1) in vec3 color;

  out vec3 ourColor;

  void main()
  {
      gl_Position = vec4(position, 1.0f); // See how we directly give a vec3 to vec4's constructor
      ourColor = color;
  }

  //Fragment shader
  #version 330 core

  in vec3 ourColor;
  out vec4 color;

  void main()
  {
      color = ourColor;
  }

我得到一个警告,我的着色器无法编译...错误是顶点着色器的零线处有一个非ascii字符.

And I'm getting a warning that my shader did not compile... error is that there is a non ascii character at line ZERO of the vertex shader.

推荐答案

我有完全相同的错误.这几乎可以肯定是由于 Unicode字节顺序标记,或由文字编辑器.

I had exactly the same error. This is almost certainly due to Unicode Byte Order Marks, or similar unprinted characters generated by text editors.

这些在unicode文件的前几个字符中很常见,但可以在任何地方出现.

These are common in the first characters of a unicode file, but can occur anywhere.

您可以在编译之前以编程方式从着色器源字符串中删除这些着色器,但是如果要编译许多着色器,这可能会很昂贵.如果您选择此路线,请参见上面的链接以获取要删除的数据.

You can programmatically strip these from your shader source strings before compiling, but this could be costly if you are compiling many shaders. See the above link for the data to strip if you go this route.

一种替代方法是简单地将文件保留为ANSI/ASCII格式.我确信大多数文本编辑器都可以设置/转换格式,但是我将 Notepad ++ 作为示例,因为这是我用来编辑GLSL的内容:

An alternative is simply to keep the files in ANSI/ASCII format. I am sure most text editors have the facility to set/convert formats, but I will give Notepad++ as an example since it's what I use to edit GLSL:

  1. 打开GLSL文件.
  2. 编码->转换为ANSI. (请注意,仅单击在ANSI中编码"不会删除字符)
  3. 保存文件.

以上内容还应去除其他容易使GLSL解析器(以及通常的C/C ++)混淆的字符.

The above should also strip other characters prone to confusing GLSL parsers (and C/C++ in general).

您可以通知用户(/开发人员)在调试版本中加载时文件格式不正确.

You could inform the user(/developer) the files are in an incorrect format on load in debug builds.

这篇关于由于非Ascii字符,顶点着色器无法编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆