-
Если дана одна текстура, то превышение координаты текстурирования более чем в единицу приводит к тайлингу. А если в одной текстуре несколько картинок, а поверхность использует только одну из этих картинок, то как выполнить тайлинг в этом случае, не прорисовывая другие картинки из текстуры???
-
можно шейдером
-
> можно шейдером
Покажешь? Шейдеров много, а я ещё их никогда не использовала. GLSL... Но мне нужно быстрее решить этот вопрос и, если можно, то проще... Может, в OpenGL можно как ещё хранить много текстур, не вызывая на каждый объект всё тормозящий метод BindTexure?
-
для работы расширениями вообще и шейдерами в частности я использовал 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
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.
-
Далее пишем непосредственно сами шейдеры. далее смотрим здесь пример шейдера с текстурированием 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;
...
-
Точно. шейдеры - лучший вариант. Дополнительно с текстурными координатами надо передавать координаты области тайла. В скором будущем обещают шейдер для фильтрации текстур, это будет делать проще. :) А пока придется в вертексном делать.
-
загрузка шейдера
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);
-
> А пока придется в вертексном делать.
Во фрагментном вы хотели сказать? В вертексном разве только контроль получиться сделать.
-
> [7] CrytoGen (27.10.09 19:09)
Ко мне можно на ты. Да, действительно ошибся. В фрагментном конечно.
-
CrytoGen, Ссылка на GLSL texturing битая : (
-
-
Может, в OpenGL можно как ещё хранить много текстур, не вызывая на каждый объект всё тормозящий метод BindTexure?Наверное, мультитекстурирование можно использовать. В основном оно предназначено для смешивания текстур друг с другом, но в принципе ничто не мешает и просто рисовать попеременно то одной, то другой (во всяком случае в D3D можно так настроить рендер). http://jerome.jouvie.free.fr/OpenGl/Tutorials/Tutorial22.php
-
Sapersky, похоже это в стократ проще и, наверное, не менее быстро по сравнению с шейдерами... А вот способ с маской, сможет мне помочь? http://pmg.org.ru/nehe/nehe20.htmПравда я ещё не совсем разобрался в этой статье...
-
> [12] 3dmax (27.10.09 23:12)
Шейдеры это очень просто. Главное разобраться. FFP уже устарел. Поэтому если хочешь заниматься играми, без шйдеров никуда.
-
> если хочешь заниматься играми, без шйдеров никуда.
а мне кажется - без хорошей идеи =)
-
> [14] tButton © (15.02.10 15:26)
Эм... это смотря кем работать... я имел ввиду, естественно, программирование игр.
|