Forum > Ported from Delphi/Kylix

Porting 3D Fractal Tree in openGL from Delphi to Lazarus

(1/2) > >>

Boleeman:
Hi All

I tried converting a 3D Fractal tree that I found on Github that uses openGL from Delphi to Lazarus.

Got it to compile in Lazarus but it then throws an Access Violation Error at the start.
I read something about GL using threads and cylquad: PGLUquadric; using pointers that may be the problem in a few messages in the Lazarus Forumn.

I also did a compile in the Community Version of Delphi and that compiled OK. The program creates it's own API Window and alters the screen resolution. I tried doing a screenshot but I think it was not successful because it was an AP window so no capture could be done? The tree looks fairly realistic.

Using the Arrow keys you can change the perspective of the fractal tree.

I added dglOpenGL.pas to the Lazarus project and fiddled with the gluQuadricTexture(cylquad,gl_true); as it complained about BooleannByte and Byte values.

I changed:

    //gluQuadricTexture(cylquad,gl_true);
    gluQuadricTexture(cylquad, 1 );

Not sure if that was the correct thing to do?

What I wanted was that the program loads in a Windows canvas/Form instead of it's own API window.



Getting a bit lost with this all the GL codes and API. Can anyone possibly help come to the rescue?

I have attached both source codes (The Lazarus converted code and the original Delphi code made by a Russian programmer and uploaded to Github)

wp:
Please post also the texture bitmap files.

wp:
Find in the attachment a Lazarus port of the project. I did go a slightly different way, though, and added a TOpenGLControl to the form which encapsulates all the overhead for creating the OpenGL rendering context, getting bitmap format, etc. It basically has two important methods: OnPaint in which all the drawing OpenGL commands go, and OnResize in which the perspective is set up. Plus some initialization work which can go into the form's OnCreate or into some dedicated Init procedure.

Cannot fully test the program because I don't have the texture bitmap files. I thus put the texture-related drawing commands into an {$IFDEF TEXTURE} block. Just activate the {$DEFINE TEXTURE} if you have the texture files (but I did not test this, and there is some chance that it may still be buggy).

Had to modify some view-related parameters because initially I did not see the tree, and I wonder why this works in Delphi.

Boleeman:
Wow, thankyou WP for the conversion of the fractal tree source code to Lazarus. Much appreciated.
"My knowledge of GL was like walking in a very dark room and stumbling everywhere"

"initially I did not see the tree, and I wonder why this works in Delphi"
I used Delphi Community version 11.3 but that program went into a console type mode and it was also going into a different graphics resolution (but I did see the tree).



The 2 textures are attached below.

I tried activating the texture bmp files but I got this error message
The way I understood you was to comment out the  //{$IFDEF TEXTURES} and replace the
FLeaf_Tex and FStem_Tex by their filenames 'leaf.bmp' and 'stem.bmp'
Maybe I misunderstood?

Incompatible types: got "Constant String" expected "LongWord"

         glEnable(GL_TEXTURE_2D);
          //{$IFDEF TEXTURES}
          glBindTexture(GL_TEXTURE_2D, 'stem.bmp');
          //{$ENDIF}
          glRotatef(-90, 1, 0, 0);
          gluQuadricTexture(FCylQuad, GL_TRUE);
          gluCylinder(FCylQuad, 0.1, 0.02, 1.5, 3, 1 );
        glPopMatrix();         


wp:
I had added the {$IFDEF}s in order to allow switching between texture and non-texture code because I did not have the texture files. To activate the texture code you simply remove the period after the opening curly brace of {.$DEFINE TEXTURES} at the top of the unit to become:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$DEFINE TEXTURES}   // a '.' removedThis way the symbol TEXTURES is defined and the code accessing the textures is activated (the editor displays inactive code in gray).

No other changes required. Well -- except for this: Colors are wrong because the red/blue channel flip is missing in the LoadTexture method. Replace it by this code (and don't forget to add FPImage and IntfGraphics to the uses clause):


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---uses  FPImage, IntfGraphics; // Load BMP texturesfunction TMainForm.LoadTexture(AFilename: String; var ATexture: GLuint): Boolean;var  pData: Pointer = nil;  W, H: Integer;  bmp: TBitmap;  x, y: Integer;  img: TLazIntfImage;  clr: TFPColor;  tmp: DWord;begin  bmp := TBitmap.Create;  try    bmp.LoadFromFile(AFileName);    W := bmp.Width;    H := bmp.Height;     // Exchange red and blue color channels    img := bmp.CreateIntfImage;    try      for y := 0 to H-1 do        for x := 0 to W-1 do        begin          clr := img.Colors[x, y];          tmp := clr.Red;          clr.Red := clr.Blue;          clr.Blue := tmp;          img.Colors[x, y] := clr;        end;      bmp.LoadFromIntfImage(img);    finally      img.Free;    end;    pData := Pointer(bmp.RawImage.Data);     if Assigned(pData) then      Result := True    else    begin      Result := False;      MessageDlg('Unable to load ' + AFileName, mtError, [mbOK], 0);      exit;    end;     glGenTextures(1, @ATexture);    glBindTexture(GL_TEXTURE_2D, ATexture);  //  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  //  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); { all of the above can be used }    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, W, H, GL_RGB, GL_UNSIGNED_BYTE, pData);  finally    bmp.Free;  end;end;

Navigation

[0] Message Index

[#] Next page

Go to full version