Fórum TList.Sort #207583
19/01/2004
0
ao código:
tenho um registro:
type TLayerLevel = ( yllLowest, yllLow, yllNormal, yllHigh, yllHighest ); PBufferData = ^TBufferData; TBufferData = record ........... Layer: TLayerLevel; Z: Single; case Integer of ......... end; PBufferList = ^TBufferList; TBufferList = array[0..MaxInt div SizeOf( TBufferData ) - 1] of TBufferData;
e tenho um Buffer:
[color=green:d1c8fc429c]Buffer: PBufferList;[/color:d1c8fc429c]
e tambem isto:
[color=green:d1c8fc429c]DrawList: TList;[/color:d1c8fc429c]
que eu altero o tamanho assim:
ReallocMem( Buffer, NewCapacity * SizeOf( TBufferData ) );
por compatibilidade com o Delphi3
tem uma hora, que preciso ordenar o Buffer pelo [i:d1c8fc429c]Layer[/i:d1c8fc429c] e pelo [i:d1c8fc429c]Z[/i:d1c8fc429c]
estou fazendo assim:
procedure TyBuffer.SortBuffer; var I: Integer; begin DrawList.Count := BufferSize; for I := 0 to BufferSize - 1 do DrawList.List[I] := @Buffer[I]; DrawList.Sort( Compare ); end;
e a função de comparação:
unction Compare( _Item1, _Item2: Pointer ): Integer; var Item1: PBufferData; Item2: PBufferData; begin Item1 := _Item1; Item2 := _Item2; if Item1.Layer > Item2.Layer then Result := 1 else if Item1.Layer < Item2.Layer then Result := -1 else if Item1.Z > Item2.Z then Result := 1 else if Item1.Z < Item2.Z then Result := -1 else Result := 0; end;
[b:d1c8fc429c]mas o problema é que, eu não sei usar essa função compare direito[/b:d1c8fc429c]
pelo que vi, ela tem que retornar um valor maios que zero, ou menor [u:d1c8fc429c]ou zero?[/u:d1c8fc429c]
a função acima funciona em partes, ordena a lista pelo [i:d1c8fc429c]layer[/i:d1c8fc429c], seguido pelo [i:d1c8fc429c]Z[/i:d1c8fc429c], mas quando a dois ou mais itens na lista que estão no mesmo layer e possuem o mesmo valor para Z, queria preservar a ordem com que os itens foram inseridos,é é isso que não está acontecendo. ´Bagunça´ a posição dos Itens
Será que alguém poderia me ajudar, caso não tenha sido claro na explicação, eu deescrevo o problema com mais detalhes.
Obrigado pela atenção :P
Marcelo Saviski
Curtir tópico
+ 0Post mais votado
19/01/2004
Brigadão pelas dica :mrgreen:
só complementado, isso é para ser usado em conjunto com um ´canvas´ próprio, com DirectX, como o ZBuffer do DirectX não funciona na minha máquina, nem na de um camarada, tivemos que implementar isso no braço, para agrupar as imagens por layer e ordenalas pela profundidade
a parte principal do código:
PBufferData = ^TBufferData; TBufferData = record pTexture: ^IDirect3DTexture8 BufferType: TBufferType; Layer: TLayerLevel; Z: Single; end; PBufferList = ^TBufferList; TBufferList = array[0..MaxInt div SizeOf( TBufferData ) - 1] of TBufferData;
tenho uma classe para controlar o Buffer de Imagens
TyBuffer = class
protected
procedure GrowBuffer; //Isso aqui aumenta o tamanho do array
procedure SortBuffer; //Isso ordena
public
BufferSize, BufferCapacity: Cardinal; {quantidade de imagens que foram adicionadas }
Buffer: PBufferList; {Aqui as imagens vão sendo colocadas desordenadamente }
DrawList: TList; //Usado para Ordenar
procedure ClearBuffer;
end;tentei fazer várias funções para ordenar o array, mas de todas, a melhor foi a Sort do TList (performance)
A parte principal está aqui:
function Compare( _Item1, _Item2: Pointer ): Integer;
var
Item1: PBufferData;
Item2: PBufferData;
begin
Item1 := _Item1;
Item2 := _Item2;
if Item1.Layer > Item2.Layer then
Result := 1
else if Item1.Layer < Item2.Layer then
Result := -1
else
if Item1.Z > Item2.Z then
Result := 1
else if Item1.Z < Item2.Z then
Result := -1
else
Result := 0;
end;
procedure TyBuffer.SortBuffer;
var
I: Integer;
begin
DrawList.Count := BufferSize;
for I := 0 to BufferSize - 1 do
DrawList.List[I] := @Buffer[I]; {Isso só para copiar os itens do array pra Lista}
DrawList.Sort( Compare );
end;
procedure TyBuffer.ClearBuffer;
begin
BufferSize := 0;
end;Depois usaria DrawList para desenhar as Imagens na Tela obedecendo as Camadas e Zs.
pensei em colocar um Index: nº; no TBufferData, toda vez que incluisse algo no array, configuraria o Index com um contador, co caso BufferSize, assim oderia preservar a ordem em que os Itens foram incluidos, colocando mas uma comparaçaõ, no lugar aonde está o [color=green:9b10ff3279]Result := 0;[/color:9b10ff3279] na procedure Compare, um [color=green:9b10ff3279]if Item1.Index > Item2.Index then Result := 1 else Result := 0[/color:9b10ff3279], dispensaria mais um else, porque eles nunca seriam iguais
seria uma solução, mas não acredito ser a mais correta
agradeço a preferência, ooops, digo, a atenção :)
Marcelo Saviski
Gostei + 1
Mais Posts
19/01/2004
Fabio.hc
Tente assim:
function Compare( _Item1, _Item2: Pointer ): Integer; var Item1: PBufferData; Item2: PBufferData; begin Item1 := _Item1; Item2 := _Item2; if (Item1.Layer = Item2.Layer) and (Item1.Z = Item2.Z) then Result := 0 else if (Item1.Layer > Item2.Layer) and (Item1.Z > Item2.Z) then Result := 1 else if (Item1.Layer < Item2.Layer) and (Item1.Z < Item2.Z) then Result := -1 else if (Item1.Layer = Item2.Layer) then begin if Item1.Z > Item2.Z then Result := 1 else if Item1.Z < Item2.Z then Result := -1 else Result := 0; end; end;
Gostei + 0
19/01/2004
Beppe
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)