问题描述
似乎我的 GLSL着色器无法编译.偶尔(主要是在编辑文件后),编译时出现以下错误:
It seems I can't have my GLSL shaders compiled. Once in a while (mainly after editing a file), I get following error while compiling:
----- SRC ----- (150 B)
#version 330 core
uniform mat4 mvpMatrix;
in vec4 vertexPosition_modelspace;
void main() {
gl_Position = mvpMatrix * vertexPosition_modelspace;
}
gp!
----- END -----
SimpleTransform.vertexshader:Vertex shader failed to compile with the following errors:
ERROR: 0:10: error(#132) Syntax error: 'gp' parse error
ERROR: error(#273) 1 compilation errors. No code generated
这很奇怪,因为我发誓文件不包含笨拙的gp!
部分.尽管如此,我还是用 cat
It's quite strange since I swear the file doesn't contain that awkward gp!
part. Nevertheless I investigated it with cat
#version 330 core
uniform mat4 mvpMatrix;
in vec4 vertexPosition_modelspace;
void main() {
gl_Position = mvpMatrix * vertexPosition_modelspace;
}
和 less
#version 330 core
uniform mat4 mvpMatrix;
in vec4 vertexPosition_modelspace;
void main() {
gl_Position = mvpMatrix * vertexPosition_modelspace;
}
他们俩都证明我是对的.
and both of them proved me right.
我想知道是什么导致了这种奇怪的行为.
I wonder what's causing this strange behaviour.
此处是我的项目的链接.您应该可以通过输入 src 目录并键入make
(仅用于 Linux )轻松地对其进行编译.它需要GLFW,GLEW,GLM和GL3.
Here's link to my project. You should be able to easily compile it by entering src directory and typing make
(Linux only). It requires GLFW, GLEW, GLM and GL3.
代码本身:
加载着色器文件
GLuint shader_load(GLenum type, const char filename[]) {
if ((type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) || !filename) return 0;
/* wczytywanie pliku shadera */
FILE *file = fopen(filename, "rb");
//okreslenie rozmiaru pliku
fseek(file, 0, SEEK_END);
uint32 iFileSize = ftell(file);
fseek(file, 0, SEEK_SET);
//wczytywanie
char *tmp = new char[iFileSize];
memset(tmp, 0, sizeof(tmp));
uint32 iBytes = (uint32) fread(tmp, sizeof(char), iFileSize, file);
fclose(file);
if (iBytes != iFileSize) printf("Warning: reading error possible!\n");
#ifdef _DEBUG_
printf("----- SRC ----- (%d B)\n%s\n----- END -----\n", iBytes, tmp);
#endif
/* przygotowanie shadera */
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, const_cast<const GLchar**>(&tmp), NULL);
delete[] tmp;
glCompileShader(shader); //kompilacja shadera
/* sprawdzenie statusu kompilacji */
int status = GL_FALSE;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
int logsize = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logsize);
char *log = new char[logsize];
glGetShaderInfoLog(shader, logsize, NULL, log);
printf("%s:%s", filename, log);
delete[] log;
if (status != GL_TRUE) return 0;
return shader;
}
推荐答案
分析:
在valgrind显示下运行
Running under valgrind shows
==15579== Invalid read of size 1
==15579== at 0x5B95C65: vfprintf (vfprintf.c:1623)
==15579== by 0x5B9E768: printf (printf.c:35)
==15579== by 0x4019C1: shader_load(unsigned int, char const*) (shaders.cpp:88)
==15579== by 0x401B30: program_create(char const*, char const*) (shaders.cpp:120)
==15579== by 0x401D65: main (in /tmp/ogl-jg-3/test)
==15579== Address 0xb3018a6 is 0 bytes after a block of size 150 alloc'd
==15579== at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15579== by 0x401961: shader_load(unsigned int, char const*) (shaders.cpp:81)
==15579== by 0x401B30: program_create(char const*, char const*) (shaders.cpp:120)
==15579== by 0x401D65: main (in /tmp/ogl-jg-3/test)
它确切地告诉您它试图读取超出在行81中分配的缓冲区tmp
的末尾.看来您以某种方式假定它为空终止.不是.添加:
It tells you exactly that it tries to read beyond the end of the buffer tmp
which is allocated in line 81. It seems you are somehow assuming it is null-terminated. Which it isn't. Add that:
//wczytywanie
char *tmp = new char[iFileSize+1];
memset(tmp, 0, (iFileSize+1)*sizeof(char));
uint32 iBytes = (uint32) fread(tmp, sizeof(char), iFileSize, file);
fclose(file);
if (iBytes != iFileSize) printf("Warning: reading error possible!\n");
#ifdef _DEBUG_
printf("----- SRC ----- (%d B)\n%s\n----- END -----\n", iBytes, tmp);
#endif
我得到半体面的输出. GL窗口保持空白
And I get semi-decent output. The GL window stays blank, though
要弄清楚我 切换到C ++ 的意思,这是一个主意:
To make it clearer what I meant by switch to C++ here's the idea:
GLuint shader_load(GLenum type, const char filename[]) {
if ((type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) || !filename) return 0;
GLuint shader = glCreateShader(type);
std::string src;
{
/* wczytywanie pliku shadera */
std::ifstream ifs(filename, std::ios::binary);
if (!std::getline(ifs, src, '\0'))
std::cerr << "Warning: reading error possible!\n";
}
#ifdef _DEBUG_
std::cout << "----- SRC ----- " << src.size() << " B \n" << src << "\n----- END -----\n";
#endif
/* przygotowanie shadera */
const GLchar* sources[] = { src.c_str() };
glShaderSource(shader, 1, sources, NULL);
glCompileShader(shader); //kompilacja shadera
这篇关于读取文件,损坏的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!