1

看来我无法编译我的GLSL 着色器。偶尔(主要是在编辑文件之后),编译时出现以下错误:

----- 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!部分。尽管如此,我还是用猫调查了它

#version 330 core

uniform mat4 mvpMatrix;

in vec4 vertexPosition_modelspace;

void main() {
    gl_Position = mvpMatrix * vertexPosition_modelspace;
}

更少_

#version 330 core

uniform mat4 mvpMatrix;

in vec4 vertexPosition_modelspace;

void main() {
    gl_Position = mvpMatrix * vertexPosition_modelspace;
}

他们都证明了我是对的。

我想知道是什么导致了这种奇怪的行为。

这是我的项目的链接。您应该能够通过输入src目录并键入make(仅限Linux)轻松编译它。它需要 GLFW、GLEW、GLM 和 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;
}
4

1 回答 1

5

首先关闭切换到 C++ 而不是 C-with-a-cpp 扩展名以避免像这样的沉船。

分析:


在 valgrind 下运行显示

==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)

它准确地告诉您它试图读取超出第tmp81 行分配的缓冲区的末尾。您似乎以某种方式假设它是空终止的。它不是。补充一点:

//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 窗口保持空白

更新

为了更清楚地说明我切换到 C++的意思,这里的想法是:

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
于 2012-08-24T23:25:53.363 回答