我正在开发一个基于着色器的简单游戏,当我的顶点着色器文件长大,它的大小达到512字节,我现在无法用c ++加载它。 我不认为这是一个常见的问题,但我想它来自我的自定义着色器加载器,而不是来自opengl限制。 这里是我的简单顶点着色器的代码(它应该将笛卡尔坐标映射到球形坐标,其大小为583bytes):
#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。 你有没有见过这样的问题?
答案 0 :(得分:5)
一个问题是,您正在使用char[]
将着色器源读取到read
缓冲区中,而无需添加NUL终结符,然后使用NULL调用glShaderSource
一个长度向量,所以它会寻找一个NUL终结符来计算字符串的长度。所以我希望随机失败,取决于在字符串后发生在内存中的情况(幸运的是它是否因NUL终止而出现,因为下一个字节恰好为0)。
您需要正确地NUL终止您的字符串,或者将指针传递给字符串的长度作为glShaderSource
的第4个参数
答案 1 :(得分:0)
在ifstream构造函数中添加std :: ifstream :: binary作为第二个参数解决了这个问题。我不完全理解为什么ifstream(默认情况下将文件视为文本文件)在文件长度达到512字节时停止计算行尾,并添加一些随机字节以匹配实际大小。无论如何,使用ifstream肯定不是加载文件的最佳方式,但就处理着色器而言,我会说这没关系(使用适当的“ios :: binary”标志)。