【问题标题】:Light per vertex shader每个顶点着色器的光
【发布时间】:2014-06-26 01:28:47
【问题描述】:

我正在尝试编译这个 glsl 着色器,但看起来有问题,因为他失败了。这是 _log 给我的消息错误:在调用 glLinkProgram() 之前没有成功编译顶点着色器。链接失败。

它是每个顶点着色器的光:

  vec4 ambient()
    {
        vec4 ambient = vec4 (0.0);
        ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
        ambient += (gl_LightModel.ambient * gl_FrontMaterial.ambient);
        return ambient;

    }

    vec4 diffuse(vec3 normal)
    {

        vec3 diffuse  = gl_LightSource[0].position * normal;

        float diff = max(dot(normal,diffuse),0.0);
        diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * diff;
        return diffuse;
    }

    vec4 specular(vec3 normal)
    {
        float hv = max(dot(normal, vec3(gl_LightSource[0].halfVector)), 0.0);

        float spec = pow(hv, gl_FrontMaterial.shininess);

        return gl_LightSource[0].specular * gl_FrontMaterial.specular * spec;
    }

    void main()
    {

        vec3 normal = normalize(gl_NormalMatrix * gl_Normal);   

        vec4 ambient = ambient();
        vec4 diffuse = diffuse(normal);
        vec4 specular = specular(normal);

        gl_FrontColor = gl_Color*(ambient+difuse)+specular;


        gl_Position = ftransform();

    }

这是着色器类:

#include "Shader.h"
namespace topicos
{

#include "Shader.h"

Shader::Shader()
{
    program = glCreateProgram();
}

Shader::~Shader()
{

    glDetachShader(program, vertexShader);
    glDetachShader(program, geometryShader);
    glDetachShader(program, fragmentShader);

    glDeleteShader(vertexShader);
    glDeleteShader(geometryShader);
    glDeleteShader(fragmentShader);

    glDeleteProgram(program);
}

void Shader::determinarFontes(std::string vertex, std::string geometry, std::string fragment)
{

    vertexFileName = vertex;
    geometryFileName = geometry;
    fragmentFileName = fragment;
}

void Shader::ativarShader()
{
    glLinkProgram(program);
    glUseProgram(program);
    programLog(program);
    shaderLog(program);

    std::cout<<_log;


}

void Shader::desativarShader()
{

    glUseProgram(0);
}

void Shader::shaderLog(unsigned int obj)
{

    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;

    glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infologLength);

    if (infologLength > 0)
    {
        infoLog = new char[infologLength];
        glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);

        std::string str(infoLog);

        if (!str.empty())
        {
            _log += "\n" + str;
        }
        else
        {
            _log += "Done.\n";
        }

        delete [] infoLog;
    }
}

void Shader::programLog(unsigned int obj)
{

    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;

    glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &infologLength);

    if (infologLength > 0)
    {
        infoLog = new char[infologLength];
        glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);

        std::string str(infoLog);

        if (!str.empty())
        {
            _log += "\n" + str;
        }
        else
        {
            _log += "Done.\n";
        }

        delete [] infoLog;
    }
}
std::string Shader::loadShader(std::string shaderFile)
{

    std::string texto = "";

    std::ifstream obj;
    obj.open(shaderFile.c_str(), std::ifstream::in);

   // std::cout << " ..>> " << obj.is_open() << std::endl;

    std::string linha;

    while(std::getline(obj, linha))
    {
        texto +=  linha + "\n";
    }
    obj.close();
//std::cout<<"texto: " << texto<< std::endl;
    return texto;
}
void Shader::makeVertexShader(const std::string& vertexFileName)
{
    /**This function creates a vertex shader,
    compiles it and attached to the program**/
    const char *stringConvertidaVertex = loadShader(vertexFileName).c_str();
    //std::cout<<"vertex shader: " << loadShader(vertexFileName)<<std::endl;
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &stringConvertidaVertex, NULL);
    glCompileShader(vertexShader);
    glAttachShader(program, vertexShader);
}
void Shader::makeFragmentShader(const std::string& fragmentFileName)
{
    /**This function creates a fragment shader,
    compiles it and attached to the program**/
    const char *stringConvertidaFragment = loadShader(fragmentFileName).c_str();
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &stringConvertidaFragment, NULL);
    glCompileShader(fragmentShader);
    glAttachShader(program, fragmentShader);
}
void Shader::makeGeometryShader(const std::string& geometryFileName)
{
    /**This function creates a fragment shader,
    compiles it and attached to the program**/
    const char *stringConvertidaGeometry = loadShader(geometryFileName).c_str();
    geometryShader = glCreateShader(GL_GEOMETRY_SHADER);
    glShaderSource(geometryShader, 1, &stringConvertidaGeometry, NULL);
    glCompileShader(geometryShader);
    glAttachShader(program, geometryShader);
}

}

任何帮助将不胜感激。

【问题讨论】:

  • 能否在您的问题中包含完整的编译错误消息?
  • 在调用 glLinkProgram() 之前没有成功编译顶点着色器。链接失败。
  • 您可能会发现 this 最近的回答很有用。

标签: glsl shader


【解决方案1】:

我认为

gl_FrontColor = gl_Color*(ambient+difuse)+specular;

应该是

gl_FrontColor = gl_Color*(ambient+diffuse)+specular;

要让驱动程序显示这些错误,以便您不必自己找到它们,请执行此操作(它是 C 语言,我不确定您使用的是哪种宿主语言)

// Checks if compilation of a shader was successful.
// On success, returns GL_TRUE. On failure, prints the
// error message to stderr and returns GL_FALSE. 
GLint check_shader_compilation_status(GLuint shader)
{
    GLchar* info_log;
    GLint r;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &r);
    if (r == GL_FALSE)
    {
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &r);
        info_log = malloc(sizeof(GLchar) * r);
        glGetShaderInfoLog(shader, r, NULL, info_log);
        fprintf(stderr, "%s", info_log);
        free(info_log);
        return GL_FALSE;
    }
    return GL_TRUE;

【讨论】:

  • 您打算什么时候向我们展示解决世界之谜、建立大统一理论的神奇信息?只是要求确保我为该活动穿着得体。
  • 阅读评论怎么样?我已经写了消息:“在调用 glLinkProgram() 之前没有成功编译顶点着色器。链接失败。”
  • 这不是来自 glGetShaderInfoLog 的消息。
  • 这个“0:13(52): 错误: 算术运算符的向量大小不匹配 0:16(10): 错误: vec4 类型的值不能分配给 vec3 类型的变量 0:17( 16): error: return' with wrong type vec3, in functiondiffuse' return vec4 [...]" 来自 glGetShaderInfoLog。这个“顶点着色器在调用 glLinkProgram() 之前没有成功编译。链接失败。”不是
【解决方案2】:

缺少版本号、尺寸不匹配和拼写错误。 (我对自己的编码风格保密。

#version 140 // ? I dislike guessing

vec4 ambient()
{
    vec4 ambient = vec4 (0.0);
    ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
    ambient += (gl_LightModel.ambient * gl_FrontMaterial.ambient);
    return ambient;

}

vec4 diffuse(vec3 normal)
{

    // vec3 diffuse  = gl_LightSource[0].position * normal;
    vec4 diffuse  = vec4(gl_LightSource[0].position.xyz * normal,1.0);

    float diff = max(dot(normal,diffuse.xyz),0.0);
    diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * diff;
    return diffuse;
}

vec4 specular(vec3 normal)
{
    float hv = max(dot(normal, vec3(gl_LightSource[0].halfVector)), 0.0);

    float spec = pow(hv, gl_FrontMaterial.shininess);

    return gl_LightSource[0].specular * gl_FrontMaterial.specular * spec;
}

void main()
{

    vec3 normal = normalize(gl_NormalMatrix * gl_Normal);   

    vec4 ambient = ambient();
    vec4 diffuse = diffuse(normal);
    vec4 specular = specular(normal);

    // gl_FrontColor = gl_Color*(ambient+difuse)+specular;
    gl_FrontColor = gl_Color*(ambient+diffuse)+specular;


    gl_Position = ftransform();

}

附录

来自http://www.khronos.org/opengles/sdk/tools/Reference-Compiler/的glslangValidator

foo.vert 上面的代码

glslangValidator foo.vert 
echo $? 
0

【讨论】:

  • 谢谢解答,还是编译不出来
  • 哦,是的;见上面的附录。
  • 这个编译器对我有什么不同?在我的代码块项目中没有编译。
  • 您希望修复您的顶点着色器错误,而不是您的“项目”。无论后者可能表示什么。
  • 当然,我测试了另一个着色器,它可以工作。我想知道错误是什么。
【解决方案3】:

已经解决了 这是每个顶点着色器的正确光照:

vec4 ambient()
{
    vec4 ambient = vec4 (0.0);
    ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
    ambient += (gl_LightModel.ambient * gl_FrontMaterial.ambient);
    return ambient;
}

vec4 diffuse(vec3 normal)
{
    vec4 diffuse=(0,0);
    vec3 lightDir = normalize(vec3(gl_LightSource[0].position));
    float diff = max(dot(normal, lightDir), 0.0);
    diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * diff;
    return diffuse;
}
vec4 specular(vec3 normal)
{
    float hv = max(dot(normal, vec3(gl_LightSource[0].halfVector.xyz)), 0.0);
    float spec = pow(hv, gl_FrontMaterial.shininess);
    return gl_LightSource[0].specular * gl_FrontMaterial.specular * spec;
}
void main()
{
    vec3 normal = normalize(gl_NormalMatrix * gl_Normal);   
   vec4 ambient = ambient();
   vec4 diffuse = diffuse(normal);
   vec4 specular = specular(normal);
    gl_FrontColor = ambient + diffuse + specular;

    gl_Position = ftransform();
}

【讨论】:

    猜你喜欢
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    相关资源
    最近更新 更多