Page 1 of 2 12 LastLast
Results 1 to 10 of 42

Thread: pascal and learning 3d

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    thanks I'll check it out

  2. #2
    OpenGL is in a strange situation now. You really should learn OpenGL 3.2+ today, not OpenGL 1/2. If you do use OpenGL 2, go for VAOs/VBOs and shaders instead of fixed pipeline.

  3. #3
    yeah, I'm after 3.2+ just had problem finding a basic example for pascal. And I didn't, even among those links but managed to craft it from old pascal opengl 2.1 and new 3.2 c++ tutorial.
    btw in c++ stack (or vector? the one with .push() and pop() is used for keeping and traversing matrices hierarchy in a convenient way. There's no vector class in delphi/pascal so what you guys are using instead?

  4. #4
    TList is comparative to C++ vector-class? I don't use it though. Dynamic arrays are very handy, and keep the data linearily in it.

  5. #5
    PGDCE Developer Carver413's Avatar
    Join Date
    Jun 2010
    Location
    Spokane,WA,Usa
    Posts
    206
    I would avoid creating classes to handle lower level stuff like vectors and matrix's use array's of record's as they are opengl friendly and well managed by fpc. never use multi dimensional array's as they will not be a single chunck of memory. for lower level stuff stick to procedural comands that dont require you to create a class ever time you want to use a command.
    Code:
     TFlt4 = packed record
        case Integer of
          0:(X,Y,Z,W:Single);
          1:(S:Array [0..3] of Single);
          2:(R,G,B,A:Single);
          3:(X1,Y1,X2,Y2:Single);
        end;
    
    TArrFlt4 = array of TFlt4;
    
    TFlt3 = packed record
      case Integer of
        0:(X,Y,Z:Single);
        1:(S:Array[0..2] of Single);
        2:(R,G,B:Single); 
      end;
    TArrFlt3 = array of TFlt3;
    
    Points:TArrFlt3;
    SetLength(Points,10);
    Points[0]:=VecFlt3(1,1,1);
    Points[1]:=Points[0];
    Points[1].X+=0.5;
    Points[1].S[2]:=2;// same as Points[1].Y but is index able Points[1].S[i]:=10;
    
    Colors:TArrFlt3;
    SetLength(Colors,10);
    Colors[i].R:=0.25;
    Colors[i].B:=0.125;
    Colors[i].G:=0;
    Colors[2]:=VecFlt3(0.5,1.0,0);
    
    Color:TFlt4;
    Color.R:=0.75;
    Color.B:=0.25;
    Color.G:=0;
    Color.A:=1.0;
    Color:=VecFlt4(1,0.75,1,1);
    
    Colors[2]:=Color;
    as I have said these record type arrays are opengl friendy you can pass them like this @Points[0]

  6. #6
    Quote Originally Posted by Carver413 View Post
    Code:
     TFlt4 = packed record
        case Integer of
          0:(X,Y,Z,W:Single);
          1:(S:Array [0..3] of Single);
          2:(R,G,B,A:Single);
          3:(X1,Y1,X2,Y2:Single);
        end;
    as I have said these record type arrays are opengl friendy you can pass them like this @Points[0]
    Should I use packed records for this purpose? the interweb says it has slower access performance than 'unpacked'

  7. #7
    Quote Originally Posted by laggyluk View Post
    Should I use packed records for this purpose? the interweb says it has slower access performance than 'unpacked'
    Packed record are usually only required when you need to load/save data in a consistent way between different compilers or even languages, or when passing to programming API routines.
    Besides that, I haven't noticed any slowdown when using packed records compared to normal records

  8. #8
    PGDCE Developer Carver413's Avatar
    Join Date
    Jun 2010
    Location
    Spokane,WA,Usa
    Posts
    206
    a packed record prevents the compiler from inserting any space into your record if the compiler were to somehow change the size of your record then opengl would not understand these changes and would not work as expected.

  9. #9
    Quote Originally Posted by laggyluk View Post
    Should I use packed records for this purpose? the interweb says it has slower access performance than 'unpacked'
    Example you quoted says packed, but it is actually byte-aligned to 32 and 64 bit, so it wouldn't make any difference.

    Code:
    TRGB1 = packed record
      r, g, b: byte;
    end;
    This is not aligned. But if you make it an array and compare size:
    Code:
    TRGB2 = record
      r, g, b: byte;
    end;
    
    arr1: array[0..255] of TRGB1;
    arr2: array[0..255] of TRGB2;
    The arr1 is 256-1280 bytes smaller than arr2. This is because if you take sizeof(TRGB1) you would get 3, but sizeof(TRGB2) would give you 4 or 8 depending on if you compile with 32 or 64 bit compiler, i guess... Now if you're dealing with OpenGL functions, you need to tell it exactly the structure of the data you are using. For that there is usually a "stride"-parameter, to describe the spacing. If you would send it color data, you should use TRGB1 style with size 3 bytes. All the data is in tight sequence without spaces in between. But actually you will notice that most records will be byte aligned anyway.

    For example shader vertex-data, that will propably be the most time-critical array of them all, is byte-aligned no matter how you twist it:
    Code:
      TModelVertex = packed record
        v, n: TVector; // 12+12 bytes
        uv: TVector2f; // 8 bytes
      end; // = 24+8 = 32 => 32/8 = 4 => aligned to 64 bits

  10. #10
    Quote Originally Posted by User137 View Post
    Example you quoted says packed, but it is actually byte-aligned to 32 and 64 bit, so it wouldn't make any difference.

    Code:
    TRGB1 = packed record
      r, g, b: byte;
    end;
    This is not aligned. But if you make it an array and compare size:
    Code:
    TRGB2 = record
      r, g, b: byte;
    end;
    
    arr1: array[0..255] of TRGB1;
    arr2: array[0..255] of TRGB2;
    The arr1 is 256-1280 bytes smaller than arr2. This is because if you take sizeof(TRGB1) you would get 3, but sizeof(TRGB2) would give you 4 or 8 depending on if you compile with 32 or 64 bit compiler, i guess... Now if you're dealing with OpenGL functions, you need to tell it exactly the structure of the data you are using. For that there is usually a "stride"-parameter, to describe the spacing. If you would send it color data, you should use TRGB1 style with size 3 bytes. All the data is in tight sequence without spaces in between. But actually you will notice that most records will be byte aligned anyway.
    Err, you got it wrong. For the sake of completeness I've just put your data types into FPC/Lazarus (1.0.2) and Delphi XE 3, and SizeOf(arr1) = SizeOf(arr2) = 768; SizeOf(TRGB1) = SizeOf(TRGB2) = 3.

    Data alignment works by aligning starting offset of your data, not the size of your data. I also believe that for such cases, "packed" keyword is deprecated, at least in Delphi. What you probably meant was data padding, but I don't see how it can be useful for TRGB1/TRGB2 in terms of performance.

    Edit: according to $Align option manual, I could reproduce data padding in the following example:

    Code:
    type
     TSomeRecord = record
       TinyValue: Byte;
       BigValue: Word;
     end;
    
     TSomeArray = array[0..9] of TSomeRecord;
    In above example, "packed" keyword does seems to have effect, specifically for "TinyValue".
    Last edited by LP; 30-11-2012 at 03:25 PM.

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •