Andrea Loforte
Andrea Loforte

Reputation: 117

glsl UNEXPECTED NEW_IDENTIFIER, expecting $end

I'm experimenting this frustrating error while compiling a fragment shader. If I try to compile the shader as it is :

#version 450 core
in vec2 tex_coord;
in flat int vertex_id;
out vec4 color;
layout (binding = 20) uniform sampler2D buildingTex;
layout (binding = 21) uniform sampler2D groundTex;
const int cube_vertices = 36;
const int ground_vertices = 4;
void main(void)
{

  if(vertex_id < cube_vertices)
    {
      float scaleF = .5f;
      vec2 scale = vec2(scaleF,scaleF);
      color = texture(buildingTex,tex_coord*scale);
    }
  if(vertex_id >= cube_vertices)
    {
      color = texture(groundTex,tex_coord);
    }


}

the compailer complains with : glsl UNEXPECTED NEW_IDENTIFIER, expecting $end.

However if I add to my fragment shader another fragment shader, that i had in another file , and then i comment all its rows like follows :

// #version 450 core

// in vec2 tex_coord;
// in flat int vertex_id;
// out vec4 color;

// layout (binding = 20) uniform sampler2D buildingTex;
// layout (binding = 21) uniform sampler2D groundTex;

// int cube_vertices;
// int ground_vertices;


// void main(void)
// {

//   if(vertex_id < cube_vertices)
//     {
//       float scaleF = .5f;
//       vec2 scale = vec2(scaleF,scaleF);
//       color = texture(buildingTex,tex_coord*scale);
//       //color = vec4(1.0,1.0,1.0,1.0);
//     }
//   if(vertex_id >= cube_vertices)
//     {
//       color = texture(groundTex,tex_coord);
//       //color = vec4(1.0,0.0,0.0,1.0);
//     }




#version 450 core
in vec2 tex_coord;
in flat int vertex_id;
out vec4 color;
layout (binding = 20) uniform sampler2D buildingTex;
layout (binding = 21) uniform sampler2D groundTex;
const int cube_vertices = 36;
const int ground_vertices = 4;
void main(void)
{

  if(vertex_id < cube_vertices)
    {
      float scaleF = .5f;
      vec2 scale = vec2(scaleF,scaleF);
      color = texture(buildingTex,tex_coord*scale);
    }
  if(vertex_id >= cube_vertices)
    {
      color = texture(groundTex,tex_coord);
    }


}

in this case the shader is compiled! I tried to remove the commented line of the old code, and seems like I can remove just some of them, while others I cannot touch, to have the shader compiled.

At this moment the shader is :

// #version 450 core

// in vec2 tex_coord;
// in flat int vertex_id;
// out vec4 color;

// layout (binding = 20) uniform sampler2D buildingTex;
// layout (binding = 21) uniform sampler2D groundTex;

// int cube_vertices;
//   if(vertex_id < cube_vertices)


#version 450 core
in vec2 tex_coord;
in flat int vertex_id;
out vec4 color;
layout (binding = 20) uniform sampler2D buildingTex;
layout (binding = 21) uniform sampler2D groundTex;
const int cube_vertices = 36;
const int ground_vertices = 4;
void main(void)
{

  if(vertex_id < cube_vertices)
    {
      float scaleF = .5f;
      vec2 scale = vec2(scaleF,scaleF);
      color = texture(buildingTex,tex_coord*scale);
    }
  if(vertex_id >= cube_vertices)
    {
      color = texture(groundTex,tex_coord);
    }


}

and seems I cannot remove anymore from the commented code.

Since this seems the most illogical problem I ever had in my life,and since the others questions having this same error warning, were solved in a way that doesn't match my case, I'm opening a new quest.

ps: I tried to make a completely new shader but it didn't work.

pps: the problem comes up after I changed the major-mode (through M-x and not modifying the init file of emacs!) of emacs in order to use the ordinary shortcut I use in cpp files, in the shaders files (.vert, .frag ...), however even restoring the default-mode and restarting emacs the shader does not compile!

EDIT: this is the method I use to load the shader

 const char* Shader::loadShader(std::string shaderPath)
  {
    std::ifstream temp_ss(shaderPath,std::ifstream::in);
    if(temp_ss)
      {
     char c;
    char *ss = new char[shader_size];

    unsigned i = 0 ;
    while(temp_ss.get(c))
      {

      ss[i++] = c;
      }

    std::cout<<std::ends;
   //ends adds a null, and then flushes the buffer
   //if i don't use it , often, the window does not show anything
   //I could use std::cout<<std::endl; in place of ends, 
   //but ends seem a more polite solution to me



//CHECK SHADER
    for(int i = 0; i < shader_size; i++)
      if(ss[i] == '\0')
        std::cout<<"shader.cpp::ERROR: NULL CHARACTER FOUND ON SHADER "<<
          shaderPath<<std::endl;

    return ss;

      }
    else
      std::clog<<"shader.cpp::loadShader() : ERROR ::: no shaders found at the path : "<<shaderPath<<std::endl;



  }

Upvotes: 0

Views: 3321

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 474536

From the OP:

TO SUMMARIZE : shader files MUST be null terminated , I modify the function that loads the shader source into the buffer like follows:

const char* Shader::loadShader(std::string shaderPath)
  {
    std::ifstream temp_ss(shaderPath,std::ifstream::in);
    if(temp_ss)
      {
     char c;
    char *ss = new char[shader_size];

    unsigned i = 0 ;
    while(temp_ss.get(c))
      {

      ss[i++] = c;
      }

    //CHECK SHADER
        bool nullTerminated = false;
    for(int i = 0; i < shader_size; i++)
      if(ss[i] == '\0')
        nullTerminated = true;

    if(!nullTerminated)
      ss[shader_size++] = '\0';

    return ss;

      }
    else
      std::clog<<"shader.cpp::loadShader() : ERROR ::: no shaders found at the path : "<<shaderPath<<std::endl;



  }

and the fragment shader compiles!

Upvotes: 3

Related Questions