Skocz do zawartości

[OpenGL] Tekstury i materiały


Brainer

Polecane posty

Witam.

 

Tytuł tematu być może zbyt wiele nie wyjaśnia, ale już spieszę z wyjaśnieniami. Otóż zastanawiam się, czy lepiej jest, żeby każdy z obiektów miał do siebie przypisany swój własny materiał/teksturę, czy posiadał jedynie indeks, przez który odwoływałby się do menedżera? Przekładając to na kod - który z wariantów jest lepszy i dlaczego?

 

.: Wariant pierwszy :.

 
type
 { .: TMaterial :. }   
 TMaterial = record
   Ambient, Diffuse, Specular, Emission: TVector;
   Shininess: Single;
 end;

 { .: TTexture :. }
 TTexture = record
   TexHandle: Cardinal;
   FileName: String;
 end;

 { .: TSceneObject :. }
 TSceneObject = class(TObject)
 public
   { Public declarations }
   // ...
   Texture: TTexture;
   Material: TMaterial;
 end;
&/ui' 
type
 { .: TMaterial :. }   
 TMaterial = record
   Ambient, Diffuse, Specular, Emission: TVector;
   Shininess: Single;
 end;

 { .: TTexture :. }
 TTexture = record
   TexHandle: Cardinal;
   FileName: String;
 end;

 { .: TManager :. }
 TManager = class(TObject)
 public
   { Public declarations }
   // ...
   Materials: array of TMaterial;
   Textures: array of TTexture;
 end;

 { .: TSceneObject :. }
 TSceneObject = class(TObject)
 public
   { Public declarations }
   // ...
   TexID, MatID: Integer;
 end;

 

Ponadto, chciałbym się dowiedzieć, czy istnieje możliwość ograniczenia częstotliwości wywoływania glBindTexture. Czytałem, że użycie tej procedury jest bardzo kosztowne i jest możliwość optymalizacji. Czy wiadomo wam coś na ten temat?

 

Bardzo proszę o jasne i rzetelne wypowiedzi. :)

 

Pozdrawiam! :D

Link do komentarza
Udostępnij na innych stronach

Wg mnie lepszy jest wariant gdy obiekt ma i liczbę i wskaźnik, i prosi manger o wskaźnik podając mu indeks i manager mu zwraca (oczywiście jest to raz zrobione, bo jak już ma wskaźnik to nie ma po co prosić). Dzięki temu kilka obiektów może mieć ten sam materiał i teksturę.

 

A co do bindowania, nie znam się na opengl, ale kupiłbym to co Toster mówi, ale wtedy każda tekstura musi mieć też listę obiektów które ją używają i może to być fajne bo wtedy manager mógłby zwalniać pamięć po teksturze, jeśli nic jej nie używa.

Baza tysięcy lotnisk: http://airportsbase.com

Link do komentarza
Udostępnij na innych stronach

CYTAT(Force @ pon, 14 sty 2008 - 09:57)

Wg mnie lepszy jest wariant gdy obiekt ma i liczbę i wskaźnik, i prosi manger o wskaźnik podając mu indeks i manager mu zwraca (oczywiście jest to raz zrobione, bo jak już ma wskaźnik to nie ma po co prosić). Dzięki temu kilka obiektów może mieć ten sam materiał i teksturę.

 

Czy to ma sens? Przecież gdy obiekt ma indeks do materiału/tekstury, niepotrzebny jest mu żaden wskaźnik. Tobie chodziło o coś takiego, tak?

 
type
 { .: TSceneObject :. }
 TSceneObject = class(TObject)
 public
   { Public declarations }
   // ...
   TexID, MatID: Integer;
   Tex: TTexture;
   Mat: TMaterial;
 end;

 

Tak chyba to zrobili w GLScene - każdy obiekt ma właściwość Material i może mieć swój materiał lub pobierać go z menedżera.

 

co do bindowan

to mozesz zrobic sortowanie po teksturze, wiec najpierw robisz binda, pozniej renderujesz wszystkie elementy z ta tekstura, pozniej kolejny bind itd.

Brzmi nieźle! :D Spróbuję to zastosować u siebie...

Link do komentarza
Udostępnij na innych stronach

Wg mnie ma sens, bo można podczas ładowania podpinać wskaźniki, po za tym Ty masz to jako vary, ja myślałem, żeby były jako property i wskaźniki są tylko do odczytu, a procedura do write dla indeksu gdy się indeks zmienia prosiła manger o nowy wskaźniki.

Hmm. To nie jest mój kod - tylko przedstawiłem w ten sposób mój tok myślenia. xD No ale po co to wszystko, gdy można po prostu przechowywać indeks i odwoływać się do menedżera wtedy, gdy chcemy użyć tekstury? Przecież nie muszę przechowywać wskaźnika w obiekcie - wystarczy indeks do odpowiedniej tekstury. No chyba że w moim rozumowaniu jest błąd...

Link do komentarza
Udostępnij na innych stronach

No a jeśli z managera coś usuniesz? to zaburzysz indeksowania, a tak to nie trzymasz indeksu a jego ID (może źle się wcześniej wyraziłem), dzięki temu można zwalniać pamięć po teksturach, bo każda mogłaby mieć licznik ile rzeczy na nią wskazuje i manager by zwiększał/zmniejszał o 1, a jakby był równy 0 to by skasował.

Baza tysięcy lotnisk: http://airportsbase.com

Link do komentarza
Udostępnij na innych stronach

to te integery z tekstur są indeksami w tablicy czy czym?

Mam na myśli coś takiego:

type
 { .: TSceneObject :. }
 TSceneObject = class(TObject)
 public
   { Public declarations }
   // ...
   TexID, MatID: Integer;

   procedure ApplyTexture();
 end;

{ ... }

procedure TSceneObject.ApplyTexture;
begin
 glEnable(GL_TEXTURE_2D);
 glBindTexture(GL_TEXTURE_2D, @TexMgr.Textures[TexID].TextureHandle);
end;

{ ... }

function TTextureManager.GetItem(I: Integer): TTexture;
begin
 if (I >= 0) and (I < Count) then
   Result := FTexArray[I];
end;

Link do komentarza
Udostępnij na innych stronach

No to widzisz, wystarczy, że usuniesz teksturę o indeksie 3, to wszystkie odwoływanie się do tych powyżej się zepsuje

Nie rozumiem. :blink: Załóżmy, że mam trzy tekstury (numeracja od zera) i usunę drugą (indeks 1), to przecież nadal pozostanie jeszcze jedna tekstura, która teraz zajmie miejsce poprzedniej. Serio już nie kminię... :huh:

 

EDIT Mam taką samą liczbę postów, jak Twój nr użytkownika, Force. :lol:

Link do komentarza
Udostępnij na innych stronach

CYTAT(Force @ pon, 14 sty 2008 - 18:56)

Wow dostaniesz toster(:P) w prezencie.

 

Przydałby mi się nowy! :)

A do tematu: no to jak usuniesz o indeksie 1, to obiekt, który miał, że tekstura ma indeks 1 będzie oteksturowany czym innym, a ten co miał indeks to zrobi AV

Z pierwszym się zgadzam, ale z drugim nie, bo przed w metodzie GetItem jest warunek, który sprawdza, czy indeks jest poprawny (nie wykracza poza zakres). :P

Link do komentarza
Udostępnij na innych stronach

lol, to wyglada jak rozmowa na gg :P

A co do tematu to z tego co mi wiadomo sortowanie wedlug tekstu nie jest najlepsza optymalizacja i przy dzisiejszych czasach to ze zmiana tekstury jest 'kosztowna' mozna sobie olac, lepiej jest posortowac obiekty wedlug osi Z i wyswietlac je od najblizej polozonych do najdalej dzieki czemu zbuffer obetnie to co jest niewidoczne przez co np. moze znaczaco zmiejszyc wywolanie fragment shadera itp.

Link do komentarza
Udostępnij na innych stronach

A co do tematu to z tego co mi wiadomo sortowanie wedlug tekstu nie jest najlepsza optymalizacja i przy dzisiejszych czasach to ze zmiana tekstury jest 'kosztowna' mozna sobie olac, lepiej jest posortowac obiekty wedlug osi Z i wyswietlac je od najblizej polozonych do najdalej dzieki czemu zbuffer obetnie to co jest niewidoczne przez co np. moze znaczaco zmiejszyc wywolanie fragment shadera itp.

To na razie jest zbyt skomplikowane jak dla mnie... :huh:

Ponawiam pytanie, który z wariantów podanych przeze mnie na początku tematu jest lepszy i dlaczego?

Link do komentarza
Udostępnij na innych stronach

Ponawiam pytanie, który z wariantów podanych przeze mnie na początku tematu jest lepszy i dlaczego?

Dla mnie żadna :D

Napisz co Ci potrzebne jakie masz wymagania określ jakie zalety wyciągniesz z kolejnych rozwiązań i czekaj na nasza odpowiedź...

Skoro już zaczęliśmy pisać kodem to proszę bardzo...

 TASEMaterial = class;
 TASESubMaterials = array of TASEMaterial;

 TASEMapType = (
   ASE_AMBIENT_MAP = 0,
   ASE_DIFFUSE_MAP = 1,
   ASE_SPECULAR_MAP = 2,
   ASE_SHINE_MAP = 3,
   ASE_SHINESTRENGTH_MAP = 4,
   ASE_SELFILLUM_MAP = 5,
   ASE_OPACITY_MAP = 6,
   ASE_FILTERCOLOR_MAP = 7,
   ASE_BUMP_MAP = 8,
   ASE_REFLECT_MAP = 9,
   ASE_REFRACT_MAP = 10
   );

 TASEClass = (
   CLASS_STANDARD,
   CLASS_SHELL,
   CLASS_MULTI
   );

 TASEMaterial = class
   sName: string;
   bClass: TASEClass; // Klasa/typ materialu

   vAmbient: TASEColor;
   vDiffuse: TASEColor;
   vSpecular: TASEColor;
   sShine: Single;
   sShineStrength: Single;
   sTransparency: Single;
   aMaps: array[TASEMapType] of TASEMap;
   pEnvTex: TEnvTexStage;
   bTwoSided: boolean;

 // Podmaterialy 
   iSubMaterials: Integer;
   aSubMaterials: TASESubMaterials;
....
end;

 TASEMap = class
 protected
   sName: string;
   sBitmapFile: string;
   sAmount: Single;

   vUVOffset: Tv2D;
   vUVTiling: Tv2D;
   sUVWAngle: Single;
   Texture: TTexture;
...
end;

www.spider.dathox.com :)

Link do komentarza
Udostępnij na innych stronach

Hmm, to może teraz zadam inne pytanie, bo tamtą sprawę sobie przemyślałem i zrobię tak, jak mówił Force. :)

 

Teraz mam problem z ułożeniem optymalnej struktury reprezentującej teksturę. Na razie mam coś takiego:

type
 { .: TTexture :. }
 TTexture = record
   TexHandle: Cardinal;

   MagFilter, MinFilter: Cardinal;
   WrapS, WrapT: Cardinal;

   case Integer of
     0: FileName: String;
     1: FileNames: array[0..5] of String;
   end;
 end;

Ten kod zadziała tylko, gdy na sześcian nałożę jedną teksturę. A co w przypadku, gdy chcę nałożyć dwie? Wtedy muszę użyć zupełnie innej procedury do określania koordynat. :(

 

Reasumując, stawiam dwa pytania:

1. W jaki sposób można poprawić tę strukturę TTexture?

2. Jak rozwiązać problem określania współrzędnych tekstur w zależności od użytego rodzaju tekstury?

 

Jeżeli coś nie jest jasne (lub ewentualnie pytania są głupie), dajcie znać.

Link do komentarza
Udostępnij na innych stronach

Pytasz o jedno później o drugie ja nie potrafię tego ogarnąć hmm...

 

CYTATTen kod zadziała tylko, gdy na sześcian nałożę jedną teksturę. A co w przypadku, gdy chcę nałożyć dwie? Wtedy muszę użyć zupełnie innej procedury do określania koordynat.

Możesz użyć vertex progrmau by przeslac koordynaty z pierwszej tekstur do drugiej. Gdy używasz multitexturingu możesz ustawiać koordynaty dla dowolnej jednostki teksturujące także dla 0wej więc nie używaj glTexCoord2f tylko glTexCoord2f tylko glMultiTexCoord2f i po kłopocie.

 

Jeżeli coś nie jest jasne (lub ewentualnie pytania są głupie), dajcie znać.

W taki sposób to masz zrobić aby wygodnie Ci się z tego korzystało. Nie napiszesz silnika za pierwszym razem nie wprowadzając w nim poprawek więc walcz testuj myśl.

Pozdrawiam!

www.spider.dathox.com :)

Link do komentarza
Udostępnij na innych stronach

CYTAT(Spider100 @ czw, 17 sty 2008 - 13:53)

Pytasz o jedno później o drugie ja nie potrafię tego ogarnąć hmm...

 

Nom po prostu mnóstwo pytań mi się na raz nasuwa. A wiem, że tutaj mogę dostać rzetelne rady. Mówią, że kto pyta, nie błądzi. Tak więc wybacz moje roztargnienie...

 

(...) Gdy używasz multitexturingu możesz ustawiać koordynaty dla dowolnej jednostki teksturujące także dla 0wej więc nie używaj glTexCoord2f tylko glTexCoord2f tylko glMultiTexCoord2f i po kłopocie.

A nie stracę na szybkości, gdy będę dla pojedynczej tekstury wykonywał glMultiTexCoord2f zamiast glTexCoord2f? :huh:

Link do komentarza
Udostępnij na innych stronach

A nie stracę na szybkości, gdy będę dla pojedynczej tekstury wykonywał glMultiTexCoord2f zamiast glTexCoord2f?

Używasz najgorszej metody rysowania siatki ... heh gorzej i tak już być nie może :P

W złych miejscach optymalizacji szukasz.

 

Pozdrawiam

Spider ^*^

www.spider.dathox.com :)

Link do komentarza
Udostępnij na innych stronach

Używasz najgorszej metody rysowania siatki ... heh gorzej i tak już być nie może :P

Czemu najgorsza? Dlatego, że nie stosuję tablic wierzchołków? :blink: Jeszcze nigdy nie bawiłem się w to - a poza tym, to dopiero zaczynam przygodę z OpenGL i takie kody to w większości z neta biorę. :rolleyes:

Link do komentarza
Udostępnij na innych stronach

Czemu najgorsza? Dlatego, że nie stosuję tablic wierzchołków? :blink: Jeszcze nigdy nie bawiłem się w to - a poza tym, to dopiero zaczynam przygodę z OpenGL i takie kody to w większości z neta biorę. :rolleyes:

 

http://www.delphi3d.net/download.php

Przejrzyj speedups szczególnie damo transfer.zip.

www.spider.dathox.com :)

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...