Here is my GL Shader objects unit (used with the SDL OpenGL extensions, etc.) if anyone is interested

Code:
Unit GL_Shaders;
{.......................................................}
//  created by Paul Nicholls
//  Copyright 2006
//  Use for anything that you want, but
//  please email me with any improvements that you may make :)
//
//  Email:
//  paul_nicholls.hotmail.com
{.......................................................}
Interface

Uses
    gl,
    glext;

Type
    TGL_Shader = Class
    Private
    Protected
        FHandle: GLuint;
    Public

        Function  LoadAndCompileShaderSource(AFileName: String): Boolean; Virtual;

        Function  GetInfoLog: String;                                     Virtual;

        Property Handle: GLuint Read FHandle;
    End;

    TGL_ARB_Shader = Class(TGL_Shader)
    Protected
    Public
        Constructor Create;   Virtual;
        Destructor  Destroy;  Override;

        Function  LoadAndCompileShaderSource(AFileName: String): Boolean; Override;

        Function  GetInfoLog: String;                                     Override;
    End;

    TGL_ARB_Vertex_Shader = Class(TGL_ARB_Shader)
    Private
    Public
        Constructor Create;   Override;
        Destructor  Destroy;  Override;
    End;

    TGL_ARB_Fragment_Shader = Class(TGL_ARB_Shader)
    Private
    Public
        Constructor Create;   Override;
        Destructor  Destroy;  Override;
    End;

    TGL_Program = Class
    Private
    Protected
        FHandle: GLuint;
    Public
        Constructor Create;                                                        Virtual;
        Destructor  Destroy;                                                       Override;

        Procedure AttachShader(Const AShader: TGL_Shader);                         Virtual;
        Procedure Link;                                                            Virtual;
        Procedure Enable;                                                          Virtual;
        Procedure Disable;                                                         Virtual;

        Procedure SetParameter(Const AName: String;
                               Const AValue: GLint);             Overload;         Virtual;
        Procedure SetParameter(Const AName: String;
                               Const AValues: Array Of GLfloat); Overload;         Virtual;
    End;

    TGL_ARB_Program = Class(TGL_Program)
    Public
        Constructor Create;                                                        Override;
        Destructor  Destroy;                                                       Override;

        Procedure AttachShader(Const AShader: TGL_Shader);                         Override;
        Procedure Link;                                                            Override;
        Procedure Enable;                                                          Override;
        Procedure Disable;                                                         Override;

        Procedure SetParameter(Const AName: String;
                               Const AValue: GLint);             Overload;         Override;
        Procedure SetParameter(Const AName: String;
                               Const AValues: Array Of GLfloat); Overload;         Override;
    End;

Implementation

Uses
    SysUtils,Classes;

Function  TGL_Shader.LoadAndCompileShaderSource(AFileName: String): Boolean;
Begin
    Result := False;
End;
{.......................................................}

{.......................................................}
Function  TGL_Shader.GetInfoLog: String;
Begin
    Result := '';
End;
{.......................................................}

{.......................................................}
Constructor TGL_ARB_Shader.Create;
Begin
    Inherited Create;

    FHandle := 0;
End;
{.......................................................}

{.......................................................}
Destructor  TGL_ARB_Shader.Destroy;
Begin
    If &#40;FHandle <> 0&#41; Then
        glDeleteObjectARB&#40;FHandle&#41;;

    Inherited Destroy;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Function  TGL_ARB_Shader.LoadAndCompileShaderSource&#40;AFileName&#58; String&#41;&#58; Boolean;
Var
    ShaderSource  &#58; TStringList;
    Source        &#58; String;
    LinkStatus    &#58; GLint;
    CompileStatus &#58; GLint;
    SourceLength  &#58; Integer;
Begin
    Result &#58;= False;

    If &#40;Not FileExists&#40;AFileName&#41;&#41; Then
        Exit;

    ShaderSource &#58;= TStringList.Create;

    Try
        ShaderSource.LoadFromFile&#40;AFileName&#41;;

        If &#40;ShaderSource.Text = ''&#41; Then
            Exit;

        Source &#58;= ShaderSource.Text;

        SourceLength &#58;= Length&#40;Source&#41;;

        glShaderSourceARB&#40;FHandle,1,@Source,@SourceLength&#41;;

        glCompileShaderARB&#40;FHandle&#41;;

        glGetObjectParameterivARB&#40;FHandle,GL_OBJECT_LINK_STATUS_ARB   , @LinkStatus&#41;;
        glGetObjectParameterivARB&#40;FHandle,GL_OBJECT_COMPILE_STATUS_ARB, @CompileStatus&#41;;

        Result &#58;= &#40;LinkStatus = 1&#41; And &#40;CompileStatus = 1&#41;;
    Finally
        ShaderSource.Free;
    End;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Function  TGL_ARB_Shader.GetInfoLog&#58; String;
Var
    InfoLog       &#58; PGLcharARB;
    InfoLogLength &#58; GLint;
Begin
    glGetObjectParameterivARB&#40;FHandle,GL_OBJECT_INFO_LOG_LENGTH_ARB,@InfoLogLength&#41;;

    GetMem&#40;InfoLog,InfoLogLength + 1&#41;;

    glGetInfoLogARB&#40;FHandle,InfoLogLength,@InfoLogLength,InfoLog&#41;;

    Result &#58;= String&#40;InfoLog&#41;;

    FreeMem&#40;InfoLog,InfoLogLength + 1&#41;;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Constructor TGL_ARB_Vertex_Shader.Create;
Begin
    Inherited Create;

    FHandle &#58;= glCreateShaderObjectARB&#40;GL_VERTEX_SHADER_ARB&#41;;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Destructor  TGL_ARB_Vertex_Shader.Destroy;
Begin
    Inherited Destroy;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Constructor TGL_ARB_Fragment_Shader.Create;
Begin
    Inherited Create;

    FHandle &#58;= glCreateShaderObjectARB&#40;GL_FRAGMENT_SHADER_ARB&#41;;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Destructor  TGL_ARB_Fragment_Shader.Destroy;
Begin
    Inherited Destroy;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Constructor TGL_Program.Create;
Begin
    Inherited Create;

    FHandle &#58;= 0;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Destructor  TGL_Program.Destroy;
Begin
    If &#40;FHandle <> 0&#41; Then
        glDeleteObjectARB&#40;FHandle&#41;;

    Inherited Destroy;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_Program.AttachShader&#40;Const AShader&#58; TGL_Shader&#41;;
Begin
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_Program.Link;
Begin
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_Program.Enable;
Begin
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_Program.Disable;
Begin
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_Program.SetParameter&#40;Const AName&#58; String;
                                   Const AValue&#58; GLint&#41;;
Begin
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_Program.SetParameter&#40;Const AName&#58; String;
                                   Const AValues&#58; Array Of GLfloat&#41;;
Begin
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Constructor TGL_ARB_Program.Create;
Begin
    Inherited Create;

    FHandle &#58;= glCreateprogramObjectARB;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Destructor  TGL_ARB_Program.Destroy;
Begin
    Inherited Destroy;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_ARB_Program.AttachShader&#40;Const AShader&#58; TGL_Shader&#41;;
Begin
    glAttachObjectARB&#40;FHandle,AShader.Handle&#41;;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_ARB_Program.Link;
Begin
    glLinkProgramARB&#40;FHandle&#41;;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_ARB_Program.Enable;
Begin
    glUseProgramObjectARB&#40;FHandle&#41;;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_ARB_Program.Disable;
Begin
    glUseProgramObjectARB&#40;0&#41;;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_ARB_Program.SetParameter&#40;Const AName&#58; String;
                                       Const AValue&#58; GLint&#41;;
Begin
    glUniform1iARB&#40;glGetUniformLocationARB&#40;FHandle,PGLCharArb&#40;AName&#41;&#41;,
        AValue&#41;;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
Procedure TGL_ARB_Program.SetParameter&#40;Const AName&#58; String;
                                       Const AValues&#58; Array Of GLfloat&#41;;
Var
    ParamCount&#58; Integer;
    NameArb   &#58; PGLCharArb;
Begin
    ParamCount &#58;= Length&#40;AValues&#41;;

    NameArb &#58;= PGLCharArb&#40;AName&#41;;
    
    Case ParamCount Of
        1&#58;  glUniform1fARB&#40;glGetUniformLocationARB&#40;FHandle, NameArb&#41;,
                AValues&#91;0&#93;&#41;;
        2&#58;  glUniform2fARB&#40;glGetUniformLocationARB&#40;FHandle, NameArb&#41;,
                AValues&#91;0&#93;,AValues&#91;1&#93;&#41;;
        3&#58;  glUniform3fARB&#40;glGetUniformLocationARB&#40;FHandle, NameArb&#41;,
                AValues&#91;0&#93;,AValues&#91;1&#93;,AValues&#91;2&#93;&#41;;
        4&#58;  glUniform4fARB&#40;glGetUniformLocationARB&#40;FHandle, NameArb&#41;,
                AValues&#91;0&#93;,AValues&#91;1&#93;,AValues&#91;2&#93;,AValues&#91;3&#93;&#41;;
    Else
    End;
End;
&#123;.......................................................&#125;

&#123;.......................................................&#125;
End.