Я работаю над простой игрой, основанной на шейдерах, и поскольку мой файл вершинных шейдеров вырос, его размер достигает 512 байт, и теперь я не могу загрузить его в c ++.
Я не думаю, что это распространенная проблема, но я думаю, что это связано с моим пользовательским загрузчиком шейдеров, а не с ограничениями opengl.
Вот код моего простого вершинного шейдера (он должен отображать декартовы координаты в сферические, его размер составляет 583 байта):
#version 330 core
uniform mat4 projection;
uniform mat4 camera;
layout (location=0) in vec3 vertex;
layout (location=1) in vec4 color;
in mat4 object;
out vec4 vColor;
void main()
{
float x=sqrt(max(1.0-0.5*pow(vertex.y,2)-0.5*pow(vertex.z,2)+pow(vertex.y*vertex.z,2)/3.0,0.0));
float y=sqrt(max(1.0-0.5*pow(vertex.x,2)-0.5*pow(vertex.z,2)+pow(vertex.x*vertex.z,2)/3.0,0.0));
float z=sqrt(max(1.0-0.5*pow(vertex.x,2)-0.5*pow(vertex.y,2)+pow(vertex.x*vertex.y,2)/3.0,0.0));
gl_Position=projection*camera*object*vec4(x,y,z,1.0);
vColor=color;
}
И код загрузчика:
GLuint vs;
vs=glCreateShader(GL_VERTEX_SHADER);
std::ifstream vertexShaderStream(_vsPath);
vertexShaderStream.seekg(0,std::ios::end);
unsigned int vsSourceLen=(unsigned int)vertexShaderStream.tellg();
vertexShaderStream.seekg(0,std::ios::beg);
char vertexShaderSource[vsSourceLen];
vertexShaderStream.read(vertexShaderSource,vsSourceLen);
vertexShaderStream.close();
const char *vsConstSource(vertexShaderSource);
glShaderSource(vs,1,&vsConstSource,NULL);
glCompileShader(vs);
int status;
glGetShaderiv(vs,GL_COMPILE_STATUS,&status);
if(!status)
{
char log[256];
glGetShaderInfoLog(vs,sizeof log,NULL,log);
std::cout << log << std::endl;
return -1;
}
Когда я уменьшаю размер ниже 512 байт (2 ^ 9 …) (511 и меньше), это работает хорошо.
Я использую GLFW3 для загрузки openGL.
Вы когда-нибудь видели такую проблему?
Одна проблема заключается в том, что вы читаете свой источник шейдера в char[]
буфер с read
без добавления NUL-терминатора, а затем вы звоните glShaderSource
с NULL для вектора длины, поэтому он будет искать терминатор NUL, чтобы выяснить длину строки. Поэтому я ожидал бы, что это произойдет случайным образом, в зависимости от того, что будет в памяти после строки (к счастью, будет ли он завершен как NUL, потому что следующий байт равен 0 или нет).
Вам нужно либо правильно NUL завершить вашу строку, либо передать указатель на длину строки в качестве 4-го аргумента glShaderSource
Добавление std :: ifstream :: binary в качестве второго параметра в конструктор ifstream решило проблему. Я не совсем понимаю, почему ifstream, который по умолчанию обрабатывает файлы как текстовые файлы, перестает считать конец строки, когда длина файла достигает 512 байт, и добавляет несколько случайных байтов, соответствующих реальному размеру. В любом случае, использование ifstream, безусловно, не лучший способ загрузки файлов, но, поскольку это просто работа с шейдерами, я бы сказал, что это нормально (с соответствующим флагом «ios :: binary»).