很简单,我只是尝试将文件加载到我的OpenGL着色器的字符串中。我尝试了以下两种方法:
std::string result = "";
std::ifstream stream(path, std::ios::in);
std::string line = "";
while (getline(stream, line))
result += line + "\n";
stream.close();
return result.c_str();
以及
std::ifstream stream(path, std::ios::in);
std::string result(std::istreambuf_iterator<char>(stream), (std::istreambuf_iterator<char>()));
stream.close();
return result.c_str();
我在shader类中使用这些方法:
std::string basePath = std::string("shaders/");
std::string vertPath = basePath + name + ".vsh";
std::string fragPath = basePath + name + ".fsh";
const char* vertSrc = loadFile(vertPath.c_str());
const char* fragSrc = loadFile(fragPath.c_str());
我创建了一个着色器,其中name
是“标准”并且都加载正常。然后我再次调用构造函数,而name
则是“fxaa”。片段着色器加载很好,但fxaa.vsh
加载如下:
#version 330 core
uniform sampler2D sampler;
uniform vec2 fbo_size;
in vec4 frag_color;
in vec2 tex_coord;
layout (location = 0) out vec4 final_color;
void main()
{
float FXAA_SPAN_MAX = 8.0;
float FXAA_REDUCE_MUL = 1.0 / 8.0;
float FXAA_REDUCE_MIN = 1.0 / 128.0;
vec3 rgbNW = texture(sampler, tex_coord + (vec2(-1.0, -1.0) / fbo_size)).rgb;
vec3 rgbNE = texture(sampler, tex_coord + (vec2(1.0, -1.0) / fbo_size)).rgb;
vec3 rgbSW = texture(sampler, tex_coord + (vec2(-1.0, 1.0) / fb
它应该像这样加载:
#version 330 core
uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
layout (location = 10) in vec3 vertex_in;
layout (location = 11) in vec4 color_in;
layout (location = 12) in vec2 tex_coord_in;
out vec4 frag_color;
out vec2 tex_coord;
void main()
{
gl_Position = projection_matrix * view_matrix *
model_matrix * vec4(vertex_in, 1.0);
frag_color = color_in;
tex_coord = tex_coord_in;
}
并且片段着色器的顶部看起来像顶点着色器加载的内容: (第1 - 21行)
#version 330 core
uniform sampler2D sampler;
uniform vec2 fbo_size;
in vec4 frag_color;
in vec2 tex_coord;
layout (location = 0) out vec4 final_color;
void main()
{
float FXAA_SPAN_MAX = 8.0;
float FXAA_REDUCE_MUL = 1.0 / 8.0;
float FXAA_REDUCE_MIN = 1.0 / 128.0;
vec3 rgbNW = texture(sampler, tex_coord + (vec2(-1.0, -1.0) / fbo_size)).rgb;
vec3 rgbNE = texture(sampler, tex_coord + (vec2(1.0, -1.0) / fbo_size)).rgb;
vec3 rgbSW = texture(sampler, tex_coord + (vec2(-1.0, 1.0) / fbo_size)).rgb;
vec3 rgbSE = texture(sampler, tex_coord + (vec2(1.0, 1.0) / fbo_size)).rgb;
vec3 rgbM = texture(sampler, tex_coord).rgb;
我是一名Java程序员,所以我不熟悉C ++的IO系统。我确信这与我的ifstream
甚至我的文件或整个文件加载器有关,但我不知道是什么。
答案 0 :(得分:1)
这是一个常见错误,与加载文件的方式无关。唯一相关的陈述是这两个:
std::string result = "";
...
return result.c_str();
result
是一个对象(类型为string
),在定义时在堆栈上被分配为局部变量。在函数结束时,它超出了范围,并被销毁,这意味着它包含的字符串数据被释放。
c_str()
方法返回指向字符串对象的内部存储的指针。一旦字符串被销毁,如上图所示在函数出口处发生,就释放内部存储器。结果是,从c_str()
方法获得的结果在此之后无效,因为它指向释放的内存。
结果,该函数返回一个指向释放内存的指针,该指针可以重用于其他内存分配。因此,如果查看返回的内容,则可以覆盖该值,因为内存由其他分配使用。一些内存分配例程故意覆盖释放的内存,特别是在调试模式下,以使这些错误更加明显。
您需要做的是从方法中返回std::string
对象,而不是const char*
。然后将正确返回该值,并将其复制到您为其指定的变量。