Конференция "Игры" » OpenGL. Модуль для работы с шейдерами.
 
  • @!!ex © (30.06.07 21:52) [0]
    Может не совсем кореектно работать, поскольку я его немного исправил(в оригинале используются несколько специфических вещей, которые нужны только в моем проекте) и не компилировал. Написанно не оптимально, но работает.

    unit Shaders;

    interface
    uses OpenGL, Classes, SysUtils, Dialogs, OGLExt;

    type
    TShaderObject = class
     public
       Constructor Create(VSFileName,FSFileName:string);
       Procedure   SetShader; virtual;
       Procedure   ResetShader;
     protected
       VS, FS, SP: integer;
       UseVS, UseFS:boolean;
     end;

    implementation
    { TShaderObject }

    function LoadShader(const src: String; const stype: GLenum): GLhandleARB;
    var
     source: PChar;
     compiled, len: Integer;
     log: String;

    function GetInfoLog(s: GLhandleARB): String;
    var
     blen, slen: Integer;
     infolog: array of Char;
    begin
     glGetObjectParameterivARB(s, GL_OBJECT_INFO_LOG_LENGTH_ARB, @blen);

     if blen > 1 then
     begin
       SetLength(infolog, blen);
       glGetInfoLogARB(s, blen, slen, @infolog[0]);
       Result := String(infolog);
       Exit;
     end;

     Result := '';
    end;
    begin
       source := PChar(src);
       len := Length(src);

       Result := glCreateShaderObjectARB(stype);

       glShaderSourceARB(Result, 1, @source, @len);
       glCompileShaderARB(Result);
       glGetObjectParameterivARB(Result, GL_OBJECT_COMPILE_STATUS_ARB, @compiled);
       log := GetInfoLog(Result);
       if compiled <> 1 then
       begin
         raise Exception.Create(log);
       end;
    end;

    function LoadShaderFromFile(const filename: String; const stype: GLenum): GLhandleARB;
    var
     txt: TStringList;
     F:TTextFile;
    begin
       txt := TStringList.Create;
       txt.LoadFromFile(filename);
       try
         Result := LoadShader(txt.Text, stype);
       except on E: Exception do
         raise Exception.Create(filename + ' contains errors!' + #10 + e.Message);
       end;

       txt.Free;
    end;

    constructor TShaderObject.Create(VSFileName, FSFileName: string);
    begin
     if CanUseShaders then
     begin
       if Length(VSFileName)>0 then if FileExists(VSFileName) then UseVS:=True else UseVS:=False;
       if Length(FSFileName)>0 then if FileExists(FSFileName) then UseFS:=True else UseFS:=False;

       SP:=glCreateProgramObjectARB();

       if UseVS then
       begin
         VS:=LoadShaderFromFile(VSFileName,GL_VERTEX_SHADER_ARB);
         glAttachObjectARB(SP,VS);
       end;

       if UseFS then
         begin
         FS:=LoadShaderFromFile(FSFileName,GL_FRAGMENT_SHADER_ARB);
         glAttachObjectARB(SP,FS);
       end;

       glLinkProgramARB(SP);
     end;
    end;

    procedure TShaderObject.ResetShader;
    begin
     if CanUseShaders then
       glUseProgramObjectARB(0);
    end;

    procedure TShaderObject.SetShader;
    begin
     if CanUseShaders then
       glUseProgramObjectARB(SP);
    end;

    end.



    Не вижу смысла писать здесь целый пример. Поскольку все элементарно.
    CanUseShaders - глобальная переменная, указывающая, можно ли юзать шейдеры.
    У меня она выставляется в true если видуха и драйвера поддерживают шейдеры.
    Constructor Create(VSFileName,FSFileName:string);

    - загружает из файлов шейдеры. Теоретически можно не указывать
    Procedure   SetShader;

    - делает шейдер активным.
    Procedure   ResetShader;

    - сбасывает шейдеры. Используется стандартная обработка. Для сброса можно вызывать метод любого шейдера.

    Понятно что это базоый класс, который можно использовать только для простых шейдеров.
    Или для порождения новых, более мощных.
    К сожалению сейчас не могу представить рабочий вариант унаследованного шейдера.
    Но там все элементарно, просто вводятся дополнительные возможности для передачи значений на конвеер.
  • @!!ex © (30.06.07 21:54) [1]
    Constructor Create(VSFileName,FSFileName:string); - загружает из файлов шейдеры. Теоретически можно не указывать
    один из шейдеров, тогда дложен использоваться стандартный, но везде где я это пытался оттестировать шейдеры переставали работать вообще.
    Так что лучше шейдеры загружать парами. У меня для этих целей лежит Default.vs Default.fs их и юзаю.
  • Yashin © (02.07.07 20:51) [2]
    Из одного файла прикольнее
  • @!!ex © (02.07.07 21:49) [3]
    > [2] Yashin ©   (02.07.07 20:51)

    не понял.. Geometric шейдеры имеете ввиду?
  • Jkot © (04.07.07 16:46) [4]
    > @!!ex ©   (02.07.07 21:49) [3]
    2 файла запихиваюся в один и ставится разбиение к примеру [fp][vp] вот и всё 2 программы в 1 =)
  • @!!ex © (04.07.07 19:05) [5]
    > [4] Jkot ©   (04.07.07 16:46)

    А смысл? Ведь они могут использоваться в разных комбинациях.
  • Jkot © (05.07.07 06:07) [6]
    Многие так делают... Честно не знаю кому как нравится, я ведь только пояснил что именнно по моему мнению Yashin хотел сказать.
  • Yashin © (08.07.07 16:55) [7]
    >А смысл? Ведь они могут использоваться в разных комбинациях.
    Мне их так отлаживать легче
 
Конференция "Игры" » OpenGL. Модуль для работы с шейдерами.
Есть новые Нет новых   [134431   +10][b:0][p:0.002]