读取文件,损坏的数据 [英] Reading file, corrupted data

查看:84
本文介绍了读取文件,损坏的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎我的 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;
}

推荐答案

紧急关闭,请改用C ++而不是C-with-a-cpp扩展名,以避免出现此类沉船事故.

FIRST OFF Switch to C++ instead of C-with-a-cpp extension to avoid shipwrecks like this.

分析:

在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

这篇关于读取文件,损坏的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆