使用ifstream加载文件到字符串加载另一个文件的不完整副本?

时间:2015-12-29 18:18:04

标签: c++ opengl glsl

很简单,我只是尝试将文件加载到我的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甚至我的文件或整个文件加载器有关,但我不知道是什么。

1 个答案:

答案 0 :(得分:1)

这是一个常见错误,与加载文件的方式无关。唯一相关的陈述是这两个:

std::string result = "";
...
return result.c_str();

result是一个对象(类型为string),在定义时在堆栈上被分配为局部变量。在函数结束时,它超出了范围,并被销毁,这意味着它包含的字符串数据被释放。

c_str()方法返回指向字符串对象的内部存储的指针。一旦字符串被销毁,如上图所示在函数出口处发生,就释放内部存储器。结果是,从c_str()方法获得的结果在此之后无效,因为它指向释放的内存。

结果,该函数返回一个指向释放内存的指针,该指针可以重用于其他内存分配。因此,如果查看返回的内容,则可以覆盖该值,因为内存由其他分配使用。一些内存分配例程故意覆盖释放的内存,特别是在调试模式下,以使这些错误更加明显。

您需要做的是从方法中返回std::string对象,而不是const char*。然后将正确返回该值,并将其复制到您为其指定的变量。