Im working on an application to render Minecraft Levels. The lighting information is stored in a Byte Array with each 4-bits belonging to a different Block in the world. Im wondering if the following should extract the 4-bits correctly:
Code:
function GetLight(Data : Pointer; ID : Integer) : Byte; begin if Odd(ID) then Result := Byte(Pointer(Cardinal(Data) + (ID-1) div 2*SizeOf(Byte))^) else Result := Byte(Pointer(Cardinal(Data) + (ID) div 2*SizeOf(Byte))^);
if Odd(ID) then begin Result := Result shl 4; Result := Result shr 4; end else Result := Result shr 4; end;
Problem is that it doesn't seem to get the correct information as parts of the level which should be bright are completely black.
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
hi,
i would try this approach:
Code:
function GetLight(Data : Pointer; ID : Integer) : Byte; var index:integer; data:byte; bits:byte; begin index := ID div 2; data := Byte(Pointer(Cardinal(Data) + index )^) if Odd(ID) then bits := data and 15; // mask lower 4 bits else bits := (data shr 4) and 15; // move upper 4 bits down Result := bits; end;
maybe the second "and 15" isn't needed. but i'm not sure if the "shr" cuts off or rotates the bits. i'm betting 80% on cuting off. and i'm not sure of the pointer-moving part. maybe i've broken it. another reason why i hate pointers...
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,
maybe this way?!
Code:
function GetLight(Data: Pointer; ID: Integer): Byte; var Index: Integer; begin Index := ID div 2; inc(PByte(Data), Index); if Odd(ID) then result := PByte(Data)^ and $0F else result := PByte(Data)^ shr 4; end;
procedure TForm1.FormCreate(Sender: TObject); var ByteArr: array of Byte; i: Integer; str: String; begin SetLength(ByteArr, 4); for i := 0 to High(ByteArr) do ByteArr[i] := i+1; str := ''; for i := 0 to 2*Length(ByteArr)-1 do str := str + IntToStr(GetLight(@ByteArr[0], i)); Caption := str; end;
this code sets the Caption to '01020304'. so if you doesn't get the right results with this code, you must check your input data.
for X := 0 to 15 do for Z := 0 to 15 do for Y := 0 to 127 do begin BlockType := Byte(Pointer(Cardinal(Blocks.Data) + (Y + ( Z * 128 + ( X * 128 * 16 ) )))^);
FBlocks[X,Y,Z].Block := BlockArray[BlockType]; FBlocks[X,Y,Z].Data.CanFall := False; FBlocks[X,Y,Z].Data.FallOffset := 0; FBlocks[X,Y,Z].Data.Light := Max(GetLight(Light.Data,(Y + ( Z * 128 + ( X * 128 * 16 ) ))),GetLight(SkyLight.Data,(Y + ( Z * 128 + ( X * 128 * 16 ) )))); if FBlocks[X,Y,Z].Data.Light > 15 then FBlocks[X,Y,Z].Data.Light := 15; end;
As far as i understand Blocks, SkyLight and BlockLight are all stored in X,Z,Y format.
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.