Typehelper und absolute

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Typehelper und absolute

Beitrag von Mathias »

Jetzt sieht es folgendermassen aus:

Code: Alles auswählen

type
  TSingleArray = array[0..15]of Single;

  TMatrix = array[0..3, 0..3] of GLfloat;

  { TMatrixfHelper }

  TMatrixfHelper = type Helper for TMatrix
    function GetList:TSingleArray;
  end;
  ...
  function TMatrixfHelper.GetList: TSingleArray;
var
  x, y: integer;
begin
  for x := 0 to 3 do begin
    for y := 0 to 3 do begin
      Result[x + y * 4] := Self[x, y];
    end;
  end;
end;
...
// Hier wird zwingend ein 1D Array gebraucht.
procedure TShader.SetUniformMat4(Name: string; Value: TMatrix);
begin
  gl.uniformMatrix4fv(GetUniformLocation(Name), False, Value.GetList);
end;
Jedes mal, wen ich Matrix.GetList aufrufe, wird das ganze Array kopiert.

Jetzt zur Frage, kann man es auf solch eine Art machen, so das nur ein Zeiger auf die List geht, so etwa wie bei "absolute"

Code: Alles auswählen

  TMatrixfHelper = type Helper for TMatrix
    List: array[0..15] of single absolute Self; // Geht das irgendwie ?
  end;    
Dies habe ich noch probiert:

Code: Alles auswählen

procedure TShader.SetUniformMat4(Name: string; Value: TMatrix);
var
  m:array[0..15] of Single absolute Value;
begin
  gl.uniformMatrix4fv(GetUniformLocation(Name), False, m);
end;
Es wird zwar ohne Fehler kompiliert, aber funktionieren tut es nicht.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Typehelper und absolute

Beitrag von fliegermichl »

Du kannst einen varianten Record verwenden.

Code: Alles auswählen

type
  TSingleArray = array[0..15] of Single;
  TMatrix = array[0..3, 0..3] of Single;

  RMixed = record
    case boolean of
     true : (sa : TSingleArray);
     false: (Matrix : TMatrix);
  end;

var 
 Mixed : RMixed;
Mixed.sa[15] := 4;
ist jetzt das gleiche wie
Mixed.Matrix[3, 3] := 4;

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Typehelper und absolute

Beitrag von Mathias »

Dafür muss man immer ".Matrix ".
Daher ist es auch keine elegante Lösung.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Typehelper und absolute

Beitrag von PascalDragon »

Mathias hat geschrieben:
Mi 5. Okt 2022, 15:59
Dafür muss man immer ".Matrix ".
Daher ist es auch keine elegante Lösung.
Dann mach eben noch 'ne Standardeigenschaft dazu:

Code: Alles auswählen

{$modeswitch advancedrecords}

type
  TRange = 0..3;
  TSingleArray = array[0..15] of Single;
  TMatrix = array[TRange, TRange] of Single;

  RMixed = record
  private
    function GetElement(aRow, aCol: TRange): Single; inline;
    procedure SetElement(aRow, aCol: TRange; aValue: Single); inline;
  public
    property Element[Row, Col: TRange]: Single read GetElement write SetElement; default;
    case boolean of
     true : (sa : TSingleArray);
     false: (Matrix : TMatrix);
  end;

function RMixed.GetElement(aRow, aCol: TRange): Single;
begin
  GetElement := Matrix[aRow, aCol];
end;

procedure RMixed.SetElement(aRow, aCol: TRange; aValue: Single);
begin
  Matrix[aRow, aCol] := aValue;
end;

var
  r: RMixed;
begin
  Writeln(r[2, 2]);
  r[1, 3] := 42;
end.
Einziger Nachteil ist, dass du das dann nicht als Teil von 'nem var-Parameter oder etwas ähnlichem, dass die Adresse benötigt, verwenden kannst.
FPC Compiler Entwickler

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Typehelper und absolute

Beitrag von kupferstecher »

fliegermichl hat geschrieben:
Mi 5. Okt 2022, 15:21
Du kannst einen varianten Record verwenden.
Wenn das funktioniert, müsste aber auch die absolute-Variante funktionieren.
Mathias hat geschrieben:
Mi 5. Okt 2022, 14:45

Code: Alles auswählen

type
  TSingleArray = array[0..15]of Single;
  TMatrix = array[0..3, 0..3] of GLfloat;
Passen denn die Datentypen überhaupt zusammen? Single <-> Double?

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Typehelper und absolute

Beitrag von fliegermichl »

GlFloat ist meines Wissens Single

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Typehelper und absolute

Beitrag von sstvmaster »

fliegermichl hat geschrieben:
Fr 7. Okt 2022, 09:11
GlFloat ist meines Wissens Single
Ja, ist Single:
...
GLfloat = Single;
GLclampf = Single;
GLdouble = Double;
...
https://raw.githubusercontent.com/sechs ... OpenGL.pas
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Typehelper und absolute

Beitrag von fliegermichl »

Ja, die absolute Version geht auch.

Code: Alles auswählen

var sa : TSingleArray;
Matrix : TMatrix absolute sa;
Dann kann man wahlweise auf Matrix mit den beiden Indizes oder auf sa mit dem linearen Index zugreifen.
Und beide können auch als var Parameter an Funktionen übergeben und von diesen beeinflusst werden.

Antworten