Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting garbage chars when reading GLSL files

Tags:

c++

opengl

I run into the following problem.I load my shaders from files.The shader program ,when trying to compile, throws these errors for the vertex and fragment shaders:

Vertex info

0(12) : error C0000: syntax error, unexpected $undefined at token ""

Fragment info

0(10) : error C0000: syntax error, unexpected $undefined at token ""

When inspecting the loaded content of the files I can see all kinds of garbage text is attached at the beginnings and the ends of the shader files.Like this one:

#version 330

layout (location = 0) in vec4 position;
layout (location = 1) in vec4 color;

smooth out vec4 theColor;

void main()
{
gl_Position = position;
theColor = color;
}ýýýý««««««««þîþîþîþ

The methods loading the shaders look as follows:

void ShaderLoader::loadShaders(char * vertexShaderFile,char *fragmentShaderFile){


vs = loadFile(vertexShaderFile,vlen);
    fs = loadFile(fragmentShaderFile,flen);

}
char *ShaderLoader::loadFile(char *fname,GLint &fSize){
ifstream::pos_type size;
char * memblock;
string text;

// file read based on example in cplusplus.com tutorial
ifstream file (fname, ios::in|ios::binary|ios::ate);
if (file.is_open())
{
size = file.tellg();
fSize = (GLuint) size;
memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
cout << "file " << fname << " loaded" << endl;
text.assign(memblock);
}
else
{
cout << "Unable to open file " << fname << endl;
exit(1);
}
return memblock;
}

I tried to change the encoding from UTF-8 top ANSI ,also tried to edit outside the visual studio but the problem still persists .Any help on this will be greatly appreciated.

like image 619
Michael IV Avatar asked Feb 13 '26 09:02

Michael IV


2 Answers

You're using C++, so I suggest you leverage that. Instead of reading into a self allocated char array I suggest you read into a std::string:

#include <string>
#include <fstream>

std::string loadFileToString(char const * const fname)
{
    std::ifstream ifile(fname);
    std::string filetext;

    while( ifile.good() ) {
        std::string line;
        std::getline(ifile, line);
        filetext.append(line + "\n");
    }

    return filetext;
}

That automatically takes care of all memory allocation and proper delimiting -- the keyword is RAII: Resource Allocation Is Initialization. Later on you can upload the shader source with something like

void glcppShaderSource(GLuint shader, std::string const &shader_string)
{
    GLchar const *shader_source = shader_string.c_str();
    GLint const shader_length = shader_string.size();

    glShaderSource(shader, 1, &shader_source, &shader_length);
}

void load_shader(GLuint shaderobject, char * const shadersourcefilename)
{
    glcppShaderSource(shaderobject, loadFileToString(shadersourcefilename));
}
like image 188
datenwolf Avatar answered Feb 14 '26 23:02

datenwolf


It looks like all you have to do is allocate one more byte of memory in which you can place a null ('\0'):

...
memblock = new char[1 + fSize]; 
file.seekg (0, ios::beg);  
file.read (memblock, size);  
file.close();  
memblock[size] = '\0';
...

edit

I changed my code to use fSize in the array rather than size, since it is a GLint, which is just a typedef over an integer. Also, I tried this fix on my machine, and it works as far as I can tell - no junk at the beginning, and none at the end.

like image 28
Ken Wayne VanderLinde Avatar answered Feb 14 '26 23:02

Ken Wayne VanderLinde



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!