Конференция "Игры" » Тайлинг текстур для OpenGL
 
  • 3dmax (27.10.09 11:43) [0]
    Если дана одна текстура, то превышение координаты текстурирования более чем в единицу приводит к тайлингу. А если в одной текстуре несколько картинок, а поверхность использует только одну из этих картинок, то как выполнить тайлинг в этом случае, не прорисовывая другие картинки из текстуры???
  • CrytoGen (27.10.09 13:07) [1]
    можно шейдером
  • 3dmax (27.10.09 18:26) [2]

    > можно шейдером

    Покажешь? Шейдеров много, а я ещё их никогда не использовала. GLSL... Но мне нужно быстрее решить этот вопрос и, если можно, то проще... Может, в OpenGL можно как ещё хранить много текстур, не вызывая на каждый объект всё тормозящий метод BindTexure?
  • CrytoGen (27.10.09 18:38) [3]
    для работы расширениями вообще и шейдерами в частности я использовал Delphi OpenGL Toolkit (DOT). Написал простенький модуль

    unit GLSLUnit;

    interface

    uses
     OpenGL, DotWindow, DotUtils, DotMath, GL, GLu, GLext, DotShaders, Windows;
    type
     TGLSL = class
     private
       shaders : array of Cardinal;
     public
       po      : Cardinal;  
       constructor Create;
       procedure LoadShader(f:String;const stype:Cardinal);
       function Compile:boolean;
       procedure Start;
       procedure Finish;
       function GetUniform(name:String):Cardinal;
       function GetAttrib(name:String):Cardinal;
       procedure SetUniform(uniform:Cardinal;value0:Integer);overload;
       procedure SetUniform(uniform:Cardinal;value0:Single);overload;
       procedure SetUniform(uniform:Cardinal;value0:Single;value1:Single);overload;
       procedure SetUniform(uniform:Cardinal;value0:Single;value1:Single;value2:Single);overload;
       procedure SetUniform(uniform:Cardinal;value0:Single;value1:Single;value2:Single;value3:Sin gle);overload;

       procedure SetUniform(name:String;value0:Integer);overload;
       procedure SetUniform(name:String;value0:Single);overload;
       procedure SetUniform(name:String;value0:Single;value1:Single);overload;
       procedure SetUniform(name:String;value0:Single;value1:Single;value2:Single);overload;
       procedure SetUniform(name:String;value0:Single;value1:Single;value2:Single;value3:Single); overload;

       procedure SetAttrib(attrib:Cardinal;value0:Single);overload;
       procedure SetAttrib(attrib:Cardinal;value0:Single;value1:Single);overload;
       procedure SetAttrib(attrib:Cardinal;value0:Single;value1:Single;value2:Single);overload;
       procedure SetAttrib(attrib:Cardinal;value0:Single;value1:Single;value2:Single;value3:Singl e);overload;
       procedure Free;
     end;

    implementation

    { TGLSL }
    Const
    WND_GLSL = 'GLSL 1.00 :';

    function TGLSL.Compile: boolean;
    var
     i,status : Integer;
     log      : String;
    begin
    po:=glCreateProgramObjectARB;
    for i:=Low(shaders) to High(shaders) do
     glAttachObjectARB(po, shaders[i]);
    glLinkProgramARB(po);
    glGetObjectParameterivARB(po, GL_OBJECT_LINK_STATUS_ARB, @status);
    log:=dotGLSLGetInfoLog(po);
    Result:=true;

    if status <> 1 then
    begin
      Result:=false;
      glDeleteObjectARB(po);
      MessageBox(0, PChar('Error while compiling'#13+log), WND_GLSL, MB_OK or MB_ICONERROR);
      exit;
    end;
    end;

    procedure TGLSL.Finish;
    begin
    glUseProgramObjectARB(0);
    end;

    function TGLSL.GetUniform(name: String): Cardinal;
    begin
    Result:=glGetUniformLocationARB(po,PGLcharARB(name));
    end;

    function TGLSL.GetAttrib(name: String): Cardinal;
    begin
    Result:=glGetAttribLocationARB(po,PGLcharARB(name));
    end;

    procedure TGLSL.LoadShader(f: String; const stype: Cardinal);
    begin
    SetLength(shaders,Length(shaders)+1);
    shaders[High(shaders)]:=dotGLSLLoadShaderFromFile(f,stype);
    end;

    procedure TGLSL.Start;
    begin
    glUseProgramObjectARB(po);
    end;

    procedure TGLSL.SetUniform(uniform: Cardinal; value0: Single);
    begin
    glUniform1fARB(uniform, value0);
    end;

    procedure TGLSL.SetUniform(uniform: Cardinal; value0: Integer);
    begin
    glUniform1iARB(uniform, value0);
    end;

    procedure TGLSL.SetUniform(uniform: Cardinal; value0, value1: Single);
    begin
    glUniform2fARB(uniform, value0,value1);
    end;

    procedure TGLSL.SetUniform(uniform: Cardinal; value0, value1, value2,
     value3: Single);
    begin
    glUniform4fARB(uniform, value0,value1,value2,value3);
    end;

    procedure TGLSL.SetUniform(uniform: Cardinal; value0, value1,
     value2: Single);
    begin
    glUniform3fARB(uniform, value0,value1,value2);
    end;

    procedure TGLSL.Free;
    begin
    glDeleteObjectARB(po);
    end;

    procedure TGLSL.SetAttrib(attrib: Cardinal; value0: Single);
    begin
    glVertexAttrib1fARB(attrib, value0);
    end;

    procedure TGLSL.SetAttrib(attrib: Cardinal; value0, value1: Single);
    begin
    glVertexAttrib2fARB(attrib, value0,value1);
    end;

    procedure TGLSL.SetAttrib(attrib: Cardinal; value0, value1, value2,
     value3: Single);
    begin
    glVertexAttrib4fARB(attrib, value0,value1,value2,value3);
    end;

    procedure TGLSL.SetAttrib(attrib: Cardinal; value0, value1,
     value2: Single);
    begin
    glVertexAttrib3fARB(attrib, value0,value1,value2);
    end;

    constructor TGLSL.Create;
    begin
    inherited;
    end;

    procedure TGLSL.SetUniform(name: String; value0: Single);
    begin
    SetUniform(GetUniform(name),value0);
    end;

    procedure TGLSL.SetUniform(name: String; value0: Integer);
    begin
    SetUniform(GetUniform(name),value0);
    end;

    procedure TGLSL.SetUniform(name: String; value0, value1: Single);
    begin
    SetUniform(GetUniform(name),value0,value1);
    end;

    procedure TGLSL.SetUniform(name: String; value0, value1, value2,
     value3: Single);
    begin
    SetUniform(GetUniform(name),value0,value1,value2,value3);
    end;

    procedure TGLSL.SetUniform(name: String; value0, value1, value2: Single);
    begin
    SetUniform(GetUniform(name),value0,value1,value2);
    end;

    end.

  • CrytoGen (27.10.09 18:52) [4]
    Далее пишем непосредственно сами шейдеры. далее смотрим здесь пример шейдера с текстурированием http://www.swiftless.com/tutorials/glsl/texturing.html.
    и выполняем во fragment shader контроль за границами, примерно так:

    ...
    vec2 mytexCoord;
    attribute vec2 minTexCoord;
    attribute vec2 maxTexCoord;
    void main(void)
    {
    mytexCoord=texCoord;
    while (mytexCoord.u<minTexCoord)
     mytexCoord.u=mytexCoord.u+maxTexCoord.u-minTexCoord.u;
    ...

  • @!!ex © (27.10.09 18:53) [5]
    Точно. шейдеры - лучший вариант.
    Дополнительно с текстурными координатами надо передавать координаты области тайла.
    В скором будущем обещают шейдер для фильтрации текстур, это будет делать проще. :)
    А пока придется в вертексном делать.
  • CrytoGen (27.10.09 18:54) [6]
    загрузка шейдера

    iso:=TGLSL.Create;
    iso.LoadShader(config.path+'..\shaders\iso.fs',GL_FRAGMENT_SHADER_ARB);
    iso.LoadShader(config.path+'..\shaders\iso.vs',GL_VERTEX_SHADER_ARB);
    iso.Compile;


    активация шейдера

            Scene.iso.Start;
            Scene.iso.SetUniform('minTexCoord',0.1,0.1);
            Scene.iso.SetUniform('maxTexCoord',0.2,0.2);

  • CrytoGen (27.10.09 19:09) [7]

    > А пока придется в вертексном делать.

    Во фрагментном вы хотели сказать? В вертексном разве только контроль получиться сделать.
  • @!!ex © (27.10.09 19:34) [8]
    > [7] CrytoGen   (27.10.09 19:09)

    Ко мне можно на ты.
    Да, действительно ошибся. В фрагментном конечно.
  • 3dmax (27.10.09 22:05) [9]
    CrytoGen, Ссылка на GLSL texturing битая : (
  • @!!ex © (27.10.09 22:30) [10]
    > [9] 3dmax   (27.10.09 22:05)

    http://tinyurl.com/yfghwqp
  • Sapersky (27.10.09 22:41) [11]
    Может, в OpenGL можно как ещё хранить много текстур, не вызывая на каждый объект всё тормозящий метод BindTexure?

    Наверное, мультитекстурирование можно использовать. В основном оно предназначено для смешивания текстур друг с другом, но в принципе ничто не мешает и просто рисовать попеременно то одной, то другой (во всяком случае в D3D можно так настроить рендер).
    http://jerome.jouvie.free.fr/OpenGl/Tutorials/Tutorial22.php
  • 3dmax (27.10.09 23:12) [12]
    Sapersky, похоже это в стократ проще и, наверное, не менее быстро по сравнению с шейдерами...

    А вот способ с маской, сможет мне помочь?
    http://pmg.org.ru/nehe/nehe20.htm

    Правда я ещё не совсем разобрался в этой статье...
  • @!!ex © (28.10.09 09:08) [13]
    > [12] 3dmax   (27.10.09 23:12)

    Шейдеры это очень просто. Главное разобраться.
    FFP уже устарел. Поэтому если хочешь заниматься играми, без шйдеров никуда.
  • tButton © (15.02.10 15:26) [14]

    > если хочешь заниматься играми, без шйдеров никуда.

    а мне кажется - без хорошей идеи =)
  • @!!ex © (15.02.10 19:31) [15]
    > [14] tButton ©   (15.02.10 15:26)

    Эм... это смотря кем работать...
    я имел ввиду, естественно, программирование игр.
 
Конференция "Игры" » Тайлинг текстур для OpenGL
Есть новые Нет новых   [134427   +37][b:0][p:0.003]