【问题标题】:C++ GLSL Linking errorC++ GLSL 链接错误
【发布时间】:2015-04-04 05:01:47
【问题描述】:

我正在开发一个 3d 引擎,但在使用 C++ 中的 GLSL 着色器时遇到了一些问题。

顶点着色器:

layout(location = 0) in vec3 vertexUP;
layout(location = 1) in vec3 vertexUV;

out vec3 UP;
out vec3 UV;

void main(){
    UP = vertexUP;//Without this line, everything works fine
    UV = vertexUV;

    gl_Position = ftransform();
 }

片段着色器:

in vec3 UP;
in vec3 UV;

out vec3 color;

uniform sampler2D rs0;
uniform sampler2D rs1;
uniform sampler2D rs2;

void main(){
    if(UV[2]==0){//Selects between different textures
        color = texture( rs0, vec2(UV[0], UV[1]) ).rgb;
    }else if(UV[2]==1){
        color = texture( rs1, vec2(UV[0], UV[1]) ).rgb;
    }else{
        color = texture( rs2, vec2(UV[0], UV[1]) ).rgb;
    }
    if(UP[0]<2){//Test thing
        color[0] = 1.0;
    }
}

我想将位置数组(位置 0)解析为片段着色器,以便将其用于照明。它编译但链接顶点着色器会产生错误: 顶点着色器链接失败,片段着色器链接。

我做错了什么?

编辑: 加载着色器的代码:

GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
    // Create the shaders
    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    // Read the Vertex Shader code from the file
    std::string VertexShaderCode;
    std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
    if(VertexShaderStream.is_open())
    {
        std::string Line = "";
        while(getline(VertexShaderStream, Line))
            VertexShaderCode += "\n" + Line;
        VertexShaderStream.close();
    }

    // Read the Fragment Shader code from the file
    std::string FragmentShaderCode;
    std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
    if(FragmentShaderStream.is_open()){
        std::string Line = "";
        while(getline(FragmentShaderStream, Line))
            FragmentShaderCode += "\n" + Line;
        FragmentShaderStream.close();
    }

    GLint Result = GL_FALSE;
    int InfoLogLength;

    // Compile Vertex Shader
    printf("Compiling shader : %s\n", vertex_file_path);
    char const * VertexSourcePointer = VertexShaderCode.c_str();
    glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
    glCompileShader(VertexShaderID);

    // Check Vertex Shader
    glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> VertexShaderErrorMessage(InfoLogLength);
    glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
    fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);

    // Compile Fragment Shader
    printf("Compiling shader : %s\n", fragment_file_path);
    char const * FragmentSourcePointer = FragmentShaderCode.c_str();
    glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
    glCompileShader(FragmentShaderID);

    // Check Fragment Shader
    glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
    glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
    fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);

    // Link the program
    fprintf(stdout, "Linking program\n");
    GLuint ProgramID = glCreateProgram();
    glAttachShader(ProgramID, VertexShaderID);
    glAttachShader(ProgramID, FragmentShaderID);
    glLinkProgram(ProgramID);

    // Check the program
    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> ProgramErrorMessage(InfoLogLength);
    glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
    fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);

    glDeleteShader(VertexShaderID);
    glDeleteShader(FragmentShaderID);

    return ProgramID;
}

【问题讨论】:

  • gl 版本是否
  • 着色器代码的开头是否有#version?默认是 1.10 版本,不支持很多你正在使用的语法。
  • 从 OpenGL 打印着色器和程序日志并发布它们。
  • 我使用的是#version 330。ftransform() 不是问题。当我删除 UP = vertexUP;顶点着色器中的行,一切正常。
  • glGetProgramInfoLog/glGetShaderInfoLog 允许访问程序/着色器错误日志。

标签: c++ opengl shader


【解决方案1】:

你不能这样做:

layout(location = 0) in vec3 vertexUP;
layout(location = 1) in vec3 vertexUV;
...
gl_Position = ftransform();

ftransform() 使用内置的gl_Vertex,并且 GL 规范要求将其别名为属性索引 0,因此 GL 无法在没有冲突的情况下分配属性索引。

您真的不应该将旧的、已弃用的内置函数与通用属性混用。如果你这样做了,你应该领导 GL 分配属性位置。

【讨论】:

  • +1,但是,更好的是,完全避免旧的不推荐使用的内置函数。它们从 3.0 开始就被弃用了,那么,6 到 7 年?
  • 我是 OpenGL 新手,因为新旧方法有点令人困惑。所以,我还在互联网上读到有另一种方法可以通过使用矩阵或其他东西来替换相机(lookAt)和位置。我对吗?更改它是否需要做很多工作,或者我可以添加另一个对象缓冲区来包含对象位置?
  • 谢谢,通过切换到带有矩阵的最新 openGL 版本,它终于可以工作了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 2011-10-24
  • 2011-10-10
  • 1970-01-01
相关资源
最近更新 更多