如何调试 GLSL 片段着色器(代码更改后程序链接错误)

How to debug GLSL Fragment shader (Program Linking error after code change)

(原标题)请帮我调试我的 glsl 光照着色器,以便它可以编译!这是我第一次调试glsl

您好,我是 opengl 的新手。我正在修改我在网上找到的另一个着色器。我在网上找到的版本效果很好,但是在我的代码中某处我在编辑时犯了一个错误。问题是我已经梳理过了,看不到它,我希望能有一些新鲜的眼光。

需要说明的是,并不是绘制的内容不正确,而是无法编译

#version 330 core
struct Material {
    sampler2D diffuse;
    sampler2D specular;
    float shininess;
    float ambient;
}; 

struct DirLight {
    vec3 direction;
    vec3 color;
    float strength;
};

struct PointLight {
    vec3 position;
    vec3 color;
    float strength;
    float active;
};

struct SpotLight {
    vec3 position;
    vec3 direction;
    float cutOff;
    float outerCutOff;

    float constant;
    float linear;
    float quadratic;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;       
};

#define NR_POINT_LIGHTS 150

in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords;

out vec4 color;

uniform vec3 viewPos;
uniform DirLight dirLight;
uniform PointLight pointLights[NR_POINT_LIGHTS];
uniform SpotLight spotLight;
uniform Material material;

// Function prototypes
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 fcolor);
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);

void main()
{    
    // Properties
    vec3 norm = normalize(Normal);
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 fragColor = texture(material.diffuse, TexCoords).rgb;
    // == ======================================
    // Our lighting is set up in 3 phases: directional, point lights and an optional flashlight
    // For  each phase, a calculate function is defined that calculates the corresponding color
    // per lamp. In the main() function we take all the calculated colors and sum them up for
    // this fragment's final color.
    // == ======================================
    // Phase 1: Directional lighting
    vec3 result = vec3(0.0f);
    //result = CalcDirLight(dirLight, norm, viewDir);

    // Phase 2: Point lights
    for(int i = 0; i < NR_POINT_LIGHTS; i++)
     {
       result += CalcPointLight(pointLights[i], norm, FragPos, viewDir, fragColor);  
    }  
    // Phase 3: Spot light
   //result += CalcSpotLight(spotLight, norm, FragPos, viewDir);    

    result += material.ambient * fragColor;
    color = vec4(result, 1.0);
}

// Calculates the color when using a directional light.
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
    vec3 lightDir = normalize(-light.direction);
    // Diffuse shading
    float diff = max(dot(normal, lightDir), 0.0);
    // Specular shading
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    // Combine results
    vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
    vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
    vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
    return (diffuse + specular);
}

// Calculates the color when using a point light.
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 fcolor)
{
    if (light.active == 1)
    {
        // Lighting
        vec3 lighting = vec3(0.0f);
        //  Diffuse
         vec3 lightDir = normalize(light.position - fragPos);
         float diff = max(dot(lightDir, normal), 0.0);
         vec3 result = light.color * diff * fcolor;      
         // Attenuation (use quadratic as we have gamma correction)
         float distance = (length(fragPos - light.position)/light.strength);
         result *= 1.0 / (distance * distance);
         lighting += result;

        vec3 reflectDir = reflect(-lightDir, normal);
        float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
        vec3 specular = spec * vec3(texture(material.specular, TexCoords)) * light.color;
        specular *= material.shininess;

        specular *= 1.0 / (distance * distance);

        vec3 toReturn = lighting + specular;
        return toReturn;
    }
    else
    {
        return vec3(0.0f, 0.0f, 0.0f);
    }
}

// Calculates the color when using a spot light.
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
    vec3 lightDir = normalize(light.position - fragPos);
    // Diffuse shading
    float diff = max(dot(normal, lightDir), 0.0);
    // Specular shading
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    // Attenuation
    float distance = length(light.position - fragPos);
    float attenuation = 1.0f / (light.constant + light.linear * distance + light.quadratic * (distance * distance));    
    // Spotlight intensity
    float theta = dot(lightDir, normalize(-light.direction)); 
    float epsilon = light.cutOff - light.outerCutOff;
    float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
    // Combine results
    vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
    vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
    vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
    ambient *= attenuation * intensity;
    diffuse *= attenuation * intensity;
    specular *= attenuation * intensity;
    return (diffuse + specular);
}

谢天谢地,我的程序确实打印出了编译错误。这是吐出来​​的。不幸的是,它指向的线不是真实的......就像它们存在但它们没有任何问题,其中一个错误指向一条没有代码的线......我没有改变它的原始片段着色器部分所以这不是问题

错误图片可在以下位置找到:https://app.box.com/s/3nrzjyu3p2smnow5zo8j0q1lbqgdf149

我试过 glslDevil,但我不知道如何导入我的着色器。

非常感谢!

编辑: 我发现的有趣的东西... 我注意到的一件有趣的事情是,如果你这样定义定向光函数

vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
    vec3 lightDir = normalize(-light.direction);
    // Diffuse shading
    float diff = max(dot(normal, lightDir), 0.0);
    // Specular shading
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    // Combine results
    vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
    vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
    vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
    return (diffuse + specular);
}

它只会抛出一个错误,即 diffuse、specular 和 ambient 不是该结构的成员(这是故意的)

你的错误日志不好

  • 这是您正在使用的工具的一些链接日志
  • 不是 OpenGL 编译日志!!!

我把你的片段着色器放入OpenGL,这是真实的编译日志(使用nVidia):

[Fragment]
Compiler error
0(94) : error C1009: "ambient" is not member of struct "DirLight"
0(95) : error C1009: "diffuse" is not member of struct "DirLight"
0(96) : error C1009: "specular" is not member of struct "DirLight"

[Program]
Linker error
Fragment info
-------------
0(94) : error C1009: "ambient" is not member of struct "DirLight"
0(95) : error C1009: "diffuse" is not member of struct "DirLight"
0(96) : error C1009: "specular" is not member of struct "DirLight"
  • 你应该为你在 OpenGL
  • 中使用的每个 shader/program 对象使用 glGetShaderInfoLog
  • 我使用类似 this

有道理:

vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
    vec3 lightDir = normalize(-light.direction);
    // Diffuse shading
    float diff = max(dot(normal, lightDir), 0.0);
    // Specular shading
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    // Combine results
    vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
    vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
    vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
    return (diffuse + specular);
}

// Combine results 之后您正在访问 struct 中未定义的字段:

struct DirLight {
    vec3 direction;
    vec3 color;
    float strength;
};

[edit1] 在 C++ 中我将我的 class 用于 GLSL:

//------------------------------------------------------------------------------
//--- GLSL program class -------------------------------------------------------
//------------------------------------------------------------------------------
class GLSLprogram       // GLSL program class
    {
public:
    AnsiString log;
    int prog_id,    // whole program
        tesc_id,    // tessellation control
        tese_id,    // tessellation evaluation
        geom_id,    // geometry
        vert_id,    // vertex
        frag_id;    // fragment

    GLSLprogram();
    GLSLprogram(GLSLprogram& a);
    ~GLSLprogram();
    GLSLprogram* operator = (const GLSLprogram *a);
    //GLSLprogram* operator = (const GLSLprogram &a);
    void bind();
    void unbind();

    void set_source_text(AnsiString tesc,AnsiString tese,AnsiString geom,AnsiString vert,AnsiString frag);  // set source texts
    void set_source_file(AnsiString tesc,AnsiString tese,AnsiString geom,AnsiString vert,AnsiString frag);  // load and set source files

    void set1f   (AnsiString name,GLfloat x);
    void set2f   (AnsiString name,GLfloat x, GLfloat y);
    void set3f   (AnsiString name,GLfloat x, GLfloat y, GLfloat z);
    void set4f   (AnsiString name,GLfloat x, GLfloat y, GLfloat z, GLfloat w);
    void set1i   (AnsiString name,GLint x);
    void set2i   (AnsiString name,GLint x, GLint y);
    void set3i   (AnsiString name,GLint x, GLint y, GLint z);
    void set4i   (AnsiString name,GLint x, GLint y, GLint z, GLint w);
    void set1fv  (AnsiString name,GLfloat *p);
    void set2fv  (AnsiString name,GLfloat *p);
    void set3fv  (AnsiString name,GLfloat *p);
    void set4fv  (AnsiString name,GLfloat *p);
    void set1iv  (AnsiString name,GLint *p);
    void set2iv  (AnsiString name,GLint *p);
    void set3iv  (AnsiString name,GLint *p);
    void set4iv  (AnsiString name,GLint *p);
    void set2x2fv(AnsiString name,GLfloat *p);
    void set3x3fv(AnsiString name,GLfloat *p);
    void set4x4fv(AnsiString name,GLfloat *p);

    void get1f   (AnsiString name,GLfloat &x);
    void get2f   (AnsiString name,GLfloat &x, GLfloat &y);
    void get3f   (AnsiString name,GLfloat &x, GLfloat &y, GLfloat &z);
    void get4f   (AnsiString name,GLfloat &x, GLfloat &y, GLfloat &z, GLfloat &w);
    void get1i   (AnsiString name,GLint &x);
    void get2i   (AnsiString name,GLint &x, GLint &y);
    void get3i   (AnsiString name,GLint &x, GLint &y, GLint &z);
    void get4i   (AnsiString name,GLint &x, GLint &y, GLint &z, GLint &w);
    void get1fv  (AnsiString name,GLfloat *p);
    void get2fv  (AnsiString name,GLfloat *p);
    void get3fv  (AnsiString name,GLfloat *p);
    void get4fv  (AnsiString name,GLfloat *p);
    void get1iv  (AnsiString name,GLint *p);
    void get2iv  (AnsiString name,GLint *p);
    void get3iv  (AnsiString name,GLint *p);
    void get4iv  (AnsiString name,GLint *p);
    void get2x2fv(AnsiString name,GLfloat *p);
    void get3x3fv(AnsiString name,GLfloat *p);
    void get4x4fv(AnsiString name,GLfloat *p);
    };
//------------------------------------------------------------------------------
GLSLprogram::GLSLprogram()
    {
    prog_id=0;
    tesc_id=0;
    tese_id=0;
    geom_id=0;
    vert_id=0;
    frag_id=0;
    }
//------------------------------------------------------------------------------
GLSLprogram::~GLSLprogram()
    {
    if (glDetachShader==NULL) return;
    if (glDeleteShader==NULL) return;
    unbind();
    if (tesc_id>0) { glDetachShader(prog_id,tesc_id); glDeleteShader(tesc_id); }
    if (tese_id>0) { glDetachShader(prog_id,tese_id); glDeleteShader(tese_id); }
    if (geom_id>0) { glDetachShader(prog_id,geom_id); glDeleteShader(geom_id); }
    if (vert_id>0) { glDetachShader(prog_id,vert_id); glDeleteShader(vert_id); }
    if (frag_id>0) { glDetachShader(prog_id,frag_id); glDeleteShader(frag_id); }
    if (prog_id>0) {                                  glDeleteShader(prog_id); }
    log="";
    }
//------------------------------------------------------------------------------
void GLSLprogram::bind()
    {
    if (glUseProgram==NULL) return;
    glUseProgram(prog_id);
    }
//------------------------------------------------------------------------------
void GLSLprogram::unbind()
    {
    if (glUseProgram==NULL) return;
    glUseProgram(0);
    }
//------------------------------------------------------------------------------
void GLSLprogram::set_source_text(AnsiString tesc,AnsiString tese,AnsiString geom,AnsiString vert,AnsiString frag)
    {
    if (glCreateProgram==NULL) return;
    if (glShaderSource==NULL) return;
    if (glCompileShader==NULL) return;
    if (glAttachShader==NULL) return;
    if (glGetShaderiv==NULL) return;
    if (glGetShaderInfoLog==NULL) return;
    if (glLinkProgram==NULL) return;

    if (glGetProgramiv==NULL) return;
    if (glGetProgramInfoLog==NULL) return;
    if (glReleaseShaderCompiler==NULL) return;

    const int _size=1024;
    char dat[_size];
    GLint status,siz=0,i;
    const char * TC = tesc.c_str();
    const char * TE = tese.c_str();
    const char * GS = geom.c_str();
    const char * VS = vert.c_str();
    const char * FS = frag.c_str();
    log="";

    if (prog_id<=0) prog_id=glCreateProgram();

    if (tesc_id<=0) tesc_id=glCreateShader(GL_TESS_CONTROL_SHADER);
    else glDetachShader(prog_id,tesc_id);
    if (tesc!="")
        {
        glShaderSource(tesc_id, 1, &TC,NULL);
        glCompileShader(tesc_id);
        glAttachShader(prog_id,tesc_id);
        glGetShaderiv(tesc_id,GL_COMPILE_STATUS,&status);
        log+="[Tessellation control]\n";
        if (status) log+="OK\n"; else log+="Compiler error\n";
        glGetShaderInfoLog(tesc_id,_size,&siz,dat);
        for (i=0;i<siz;i++) log+=dat[i];

        }

    if (tese_id<=0) tese_id=glCreateShader(GL_TESS_EVALUATION_SHADER);
    else glDetachShader(prog_id,tese_id);
    if (tese!="")
        {
        glShaderSource(tese_id, 1, &TE,NULL);
        glCompileShader(tese_id);
        glAttachShader(prog_id,tese_id);
        glGetShaderiv(tese_id,GL_COMPILE_STATUS,&status);
        log+="[Tessellation evaluation]\n";
        if (status) log+="OK\n"; else log+="Compiler error\n";
        glGetShaderInfoLog(tese_id,_size,&siz,dat);
        for (i=0;i<siz;i++) log+=dat[i];

        }
    if (geom_id<=0) geom_id=glCreateShader(GL_GEOMETRY_SHADER);
    else glDetachShader(prog_id,geom_id);
    if (geom!="")
        {
        glShaderSource(geom_id, 1, &GS,NULL);
        glCompileShader(geom_id);
        glAttachShader(prog_id,geom_id);
        glGetShaderiv(geom_id,GL_COMPILE_STATUS,&status);
        log+="[Geometry]\n";
        if (status) log+="OK\n"; else log+="Compiler error\n";
        glGetShaderInfoLog(geom_id,_size,&siz,dat);
        for (i=0;i<siz;i++) log+=dat[i];

        }
    if (vert_id<=0) vert_id=glCreateShader(GL_VERTEX_SHADER);
    else glDetachShader(prog_id,vert_id);
    if (vert!="")
        {
        glShaderSource(vert_id, 1, &VS,NULL);
        glCompileShader(vert_id);
        glAttachShader(prog_id,vert_id);
        glGetShaderiv(vert_id,GL_COMPILE_STATUS,&status);
        log+="[Vertex]\n";
        if (status) log+="OK\n"; else log+="Compiler error\n";
        glGetShaderInfoLog(vert_id,_size,&siz,dat);
        for (i=0;i<siz;i++) log+=dat[i];
        }
    if (frag_id<=0) frag_id=glCreateShader(GL_FRAGMENT_SHADER);
    else glDetachShader(prog_id,frag_id);
    if (frag!="")
        {
        glShaderSource(frag_id, 1, &FS,NULL);
        glCompileShader(frag_id);
        glAttachShader(prog_id,frag_id);
        glGetShaderiv(frag_id,GL_COMPILE_STATUS,&status);
        log+="\n[Fragment]\n";
        if (status) log+="OK\n"; else log+="Compiler error\n";
        glGetShaderInfoLog(frag_id,_size,&siz,dat);
        for (i=0;i<siz;i++) log+=dat[i];
        }

    glLinkProgram(prog_id);
    glGetProgramiv(prog_id,GL_LINK_STATUS,&status);
    log+="\n[Program]\n";
    if (status) log+="OK\n"; else log+="Linker error\n";
    glGetProgramInfoLog(prog_id,_size,&siz,dat);
    for (i=0;i<siz;i++) log+=dat[i];

    glReleaseShaderCompiler();
    }
//------------------------------------------------------------------------------
void GLSLprogram::set_source_file(AnsiString tesc,AnsiString tese,AnsiString geom,AnsiString vert,AnsiString frag)
    {
    set_source_text(load(tesc),load(tese),load(geom),load(vert),load(frag));
    }
//------------------------------------------------------------------------------
void GLSLprogram::set1f   (AnsiString name,GLfloat x)                                 { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform1f  (id,x);       }
void GLSLprogram::set2f   (AnsiString name,GLfloat x, GLfloat y)                      { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform2f  (id,x,y);     }
void GLSLprogram::set3f   (AnsiString name,GLfloat x, GLfloat y, GLfloat z)           { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform3f  (id,x,y,z);   }
void GLSLprogram::set4f   (AnsiString name,GLfloat x, GLfloat y, GLfloat z, GLfloat w){ GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform4f  (id,x,y,z,w); }
void GLSLprogram::set1i   (AnsiString name,GLint x)                                   { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform1i  (id,x);       }
void GLSLprogram::set2i   (AnsiString name,GLint x, GLint y)                          { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform2i  (id,x,y);     }
void GLSLprogram::set3i   (AnsiString name,GLint x, GLint y, GLint z)                 { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform3i  (id,x,y,z);   }
void GLSLprogram::set4i   (AnsiString name,GLint x, GLint y, GLint z, GLint w)        { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform4i  (id,x,y,z,w); }
void GLSLprogram::set1fv  (AnsiString name,GLfloat *p)                                { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform1fv (id,1,p);     }
void GLSLprogram::set2fv  (AnsiString name,GLfloat *p)                                { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform2fv (id,2,p);     }
void GLSLprogram::set3fv  (AnsiString name,GLfloat *p)                                { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform3fv (id,3,p);     }
void GLSLprogram::set4fv  (AnsiString name,GLfloat *p)                                { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform4fv (id,4,p);     }
void GLSLprogram::set1iv  (AnsiString name,GLint *p)                                  { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform1iv (id,1,p);     }
void GLSLprogram::set2iv  (AnsiString name,GLint *p)                                  { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform2iv (id,2,p);     }
void GLSLprogram::set3iv  (AnsiString name,GLint *p)                                  { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform3iv (id,3,p);     }
void GLSLprogram::set4iv  (AnsiString name,GLint *p)                                  { GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniform4iv (id,4,p);     }
void GLSLprogram::set2x2fv(AnsiString name,GLfloat *p)                                { GLboolean q=true; GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniformMatrix2fv(id, 4,q,p); }
void GLSLprogram::set3x3fv(AnsiString name,GLfloat *p)                                { GLboolean q=true; GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniformMatrix3fv(id, 9,q,p); }
void GLSLprogram::set4x4fv(AnsiString name,GLfloat *p)                                { GLboolean q=true; GLint id=glGetUniformLocation(prog_id,name.c_str()); glUniformMatrix4fv(id,16,q,p); }
//------------------------------------------------------------------------------
void GLSLprogram::get1f   (AnsiString name,GLfloat &x){ GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformfv(prog_id,id,&x); }
void GLSLprogram::get1i   (AnsiString name,GLint &x)  { GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformiv(prog_id,id,&x); }
void GLSLprogram::get1fv  (AnsiString name,GLfloat *p){ GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformfv(prog_id,id,p);  }
void GLSLprogram::get2fv  (AnsiString name,GLfloat *p){ GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformfv(prog_id,id,p);  }
void GLSLprogram::get3fv  (AnsiString name,GLfloat *p){ GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformfv(prog_id,id,p);  }
void GLSLprogram::get4fv  (AnsiString name,GLfloat *p){ GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformfv(prog_id,id,p);  }
void GLSLprogram::get1iv  (AnsiString name,GLint *p)  { GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformiv(prog_id,id,p);  }
void GLSLprogram::get2iv  (AnsiString name,GLint *p)  { GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformiv(prog_id,id,p);  }
void GLSLprogram::get3iv  (AnsiString name,GLint *p)  { GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformiv(prog_id,id,p);  }
void GLSLprogram::get4iv  (AnsiString name,GLint *p)  { GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformiv(prog_id,id,p);  }
void GLSLprogram::get2x2fv(AnsiString name,GLfloat *p){ GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformfv(prog_id,id,p);  }
void GLSLprogram::get3x3fv(AnsiString name,GLfloat *p){ GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformfv(prog_id,id,p);  }
void GLSLprogram::get4x4fv(AnsiString name,GLfloat *p){ GLint id=glGetUniformLocation(prog_id,name.c_str()); glGetUniformfv(prog_id,id,p);  }
//------------------------------------------------------------------------------
  • AnsiString 只是 VCL 字符串 class(自重定位字符串 class)可以使用其他任何东西,例如 char[]char* 而不是,但您需要处理粗运算符...

  • AnsiString().c_str() returns char* 存储字符串的兼容指针

用法:

// [variables]
GLSLprogram   shader;
// [init]
shader.set_source_text("","","","your vertex shader source text","your fragment shader source text");
shader.log; // contains the compile/link log ...
shader.prog_id; // contains the OpenGL id for your shader object


// [render]
shader.bind();
// here render
shader.unbind();

[edit2] 而且我忘了添加:

AnsiString load(AnsiString file)
    {
    int i,hnd,siz;
    char *dat=NULL;
    hnd=FileOpen(file,fmOpenRead);
    if (hnd<0) return "";
    siz=FileSeek(hnd,0,2);
        FileSeek(hnd,0,0);
    if (siz==0) { FileClose(hnd); return ""; }
    dat=new char[siz+1];
    if (dat==NULL) { FileClose(hnd); return ""; }
    FileRead(hnd,dat,siz);
    FileClose(hnd);
    AnsiString s=""; for (i=0;i<siz;i++) s+=dat[i];
    delete dat;
    return s;
    }