Results 1 to 3 of 3

Thread: DelphiX and lights in Immediate mode

  1. #1

    DelphiX and lights in Immediate mode

    Does anyone know how can I have lights in DelphiX immediate mode? I tried


    DXDraw.D3DDevice7.SetLight(0, light);
    DXDraw.D3DDevice7.LightEnable(0, true);
    and
    DXDraw.D3DDevice7.SetRenderState(D3DRENDERSTATE_LI GHTING, 1);

    but it didn't work.

    Can anyone post a working source code example, or a link to such an example?


    The source code look like this:


    Code:
    unit Main;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, DXClass, DXDraws, DirectX, MMSystem, D3DUtils, ExtCtrls;
    
    type
      TMainForm = class(TDXForm)
        DXTimer: TDXTimer;
        DXImageList: TDXImageList;
        Panel1: TPanel;
        DXDraw: TDXDraw;
        procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
        procedure FormKeyDown(Sender: TObject; var Key: Word;
          Shift: TShiftState);
        procedure DXDrawInitializeSurface(Sender: TObject);
        procedure DXDrawInitialize(Sender: TObject);
        procedure DXDrawFinalize(Sender: TObject);
      private
        g_Vertices: array[0..64 * 64 - 1] of TD3DVertex;
        g_Indexes: array[0..63 * 63 * 6 - 1] of word;
        FTexture: array[0..0] of TDirect3DTexture2;
        procedure MakeLandScape;
        procedure AddLight;
        procedure FrameMovie(Time: Double);
      end;
    
    var
      MainForm: TMainForm;
    
    implementation
    
    {$R *.DFM}
    
    procedure TMainForm.DXDrawInitialize(Sender: TObject);
    var
      i: Integer;
    begin
      for i:=Low(FTexture) to High(FTexture) do
        FTexture[i] := TDirect3DTexture2.Create(DXDraw, DXImageList.Items[i].Picture.Graphic, False);
    end;
    
    procedure TMainForm.DXDrawFinalize(Sender: TObject);
    var
      i: Integer;
    begin
      for i:=Low(FTexture) to High(FTexture) do
      begin
        FTexture[i].Free;
        FTexture[i] := nil;
      end;
    end;
    
    procedure TMainForm.MakeLandScape;
    var
      n0: TD3DVector;
      i, j, k: integer;
    begin
      // Define the normals for the landscape
      n0 := MakeD3DVector( 0.0, 1.0, 0.0 );
    
    
      randseed := 1;
      i := 0;
      for j := 0 to 63 do
        g_Vertices[i * 64 + j] :=
          MakeD3DVERTEX(
            MakeD3DVECTOR(i - 32.0, random, j - 32.0),
              n0, i - 32.0, j - 32.0);
    
      for i := 1 to 63 do
      begin
        j := 0;
        g_Vertices[i * 64 + j] :=
          MakeD3DVERTEX(
            MakeD3DVECTOR(i - 32.0, random, j - 32.0),
              n0, i - 32.0, j - 32.0);
    
        for j := 1 to 63 do
          g_Vertices[i * 64 + j] :=
            MakeD3DVERTEX(
              MakeD3DVECTOR(i - 32.0,
                (g_Vertices[i * 64 + j - 1].y + g_Vertices[(i - 1) * 64 + j].y) /2 + 0.5 - random,
                  j - 32.0),
                n0, i/4, j/4);
      end;
    
      k := 0;
      for i := 0 to 62 do
        for j := 0 to 62 do
        begin
          g_Indexes[k] := i * 64 + j;
          inc(k);
          g_Indexes[k] := i * 64 + j + 1;
          inc(k);
          g_Indexes[k] := (i + 1) * 64 + j;
          inc(k);
          g_Indexes[k] := g_Indexes[k - 1];
          inc(k);
          g_Indexes[k] := g_Indexes[k - 3];
          inc(k);
          g_Indexes[k] := (i + 1) * 64 + j + 1;
          inc(k);
        end;
    end;
    
    procedure TMainForm.FrameMovie(Time: Double);
    var matView, matRotate: TD3DMatrix;
    begin
      FilLChar(matView, SizeOf(matView), 0);
      matView._11 := 0.75;
      matView._22 :=  cos(-0.5);
      matView._23 :=  sin(-0.5);
      matView._32 := -sin(-0.5);
      matView._33 :=  cos(-0.5);
      matView._41 := 5.0;
      matView._43 := 5.0;
      matView._44 := 0.1;
      DXDraw.D3DDevice7.SetTransform( D3DTRANSFORMSTATE_VIEW, matView);
    
      // Set the world matrix to rotate along the y-axis, in sync with the
      // timekey
      FillChar(matRotate, SizeOf(matRotate), 0);
      matRotate._11 :=  cos(-Time);
      matRotate._13 :=  sin(Time);
      matRotate._22 :=  1.0;
      matRotate._31 := -sin(Time);
      matRotate._33 :=  cos(Time);
      matRotate._44 :=  1.0;
      DXDraw.D3DDevice7.SetTransform( D3DTRANSFORMSTATE_WORLD, matRotate);
    end;
    
    procedure TMainForm.DXDrawInitializeSurface(Sender: TObject);
    var
      vp: TD3DViewport7;
      mtrl: TD3DMaterial7;
      matProj: TD3DMatrix;
    begin
      { Viewport }
      FillChar(vp, SizeOf(vp), 0);
      vp.dwX := 0;
      vp.dwY := 0;
      vp.dwWidth := DXDraw.SurfaceWidth;
      vp.dwHeight := DXDraw.SurfaceHeight;
      vp.dvMinZ := 0.0;
      vp.dvMaxZ := 1.0;
    
      DXDraw.D3DDevice7.SetViewport(vp);
    
      {  Material  }
      FillChar(mtrl, SizeOf(mtrl), 0);
      mtrl.ambient.r := 1.0;
      mtrl.ambient.g := 1.0;
      mtrl.ambient.b := 1.0;
      mtrl.ambient.a := 1.0;
      mtrl.diffuse.r := 1.0;
      mtrl.diffuse.g := 1.0;
      mtrl.diffuse.b := 1.0;
      mtrl.diffuse.a := 1.0;
      mtrl.specular.r := 1.0;
      mtrl.specular.g := 1.0;
      mtrl.specular.b := 1.0;
      mtrl.specular.a := 1.0;
      DXDraw.D3DDevice7.SetMaterial(mtrl);
    
      // Set the projection matrix. Note that the view and world matrices are
      // set in the App_FrameMove() function, so they can be animated each
      // frame.
      FilLChar(matProj, SizeOf(matProj), 0);
      matProj._11 :=  1.0;
      matProj._22 :=  1.0;
      matProj._33 :=  1.0;
      matProj._34 :=  1.0;
      matProj._43 := -1.0;
      DXDraw.D3DDevice7.SetTransform( D3DTRANSFORMSTATE_PROJECTION, matProj );
    
      DXDraw.D3DDevice7.SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1);
    
      DXDraw.D3DDevice7.LightEnable(0, true);
    
      DXDraw.D3DDevice7.SetRenderState(D3DRENDERSTATE_SPECULARENABLE, 1);
      DXDraw.D3DDevice7.SetRenderState(D3DRENDERSTATE_DIFFUSEMATERIALSOURCE, 0);
      DXDraw.D3DDevice7.SetRenderState(D3DRENDERSTATE_LIGHTING, 1);
      DXDraw.D3DDevice7.SetRenderState(D3DRENDERSTATE_SHADEMODE, 1);
      DXDraw.D3DDevice7.SetRenderState(D3DRENDERSTATE_AMBIENT, $A0A0A0A0);
    
      { Make landscape }
      MakeLandScape;
    end;
    
    procedure TMainForm.AddLight;
    var light: TD3DLight7;
    begin
      FillChar(light, sizeof(light), chr(0));
    
      light.dltType := D3DLIGHT_POINT;
      light.dcvDiffuse.r := 1.0;
      light.dcvDiffuse.g := 1.0;
      light.dcvDiffuse.b := 1.0;
      light.dcvSpecular.r := 1.0;
      light.dcvSpecular.g := 1.0;
      light.dcvSpecular.b := 1.0;
      light.dcvAmbient.b := 1.0;
      light.dcvAmbient.g := 1.0;
      light.dcvAmbient.b := 1.0;
      light.dvPosition := VectorMulS(MakeD3DVector(1,1,0), 4.5);
      light.dvAttenuation1 := 0.4;
      light.dvRange := D3DLIGHT_RANGE_MAX;
    
      DXDraw.D3DDevice7.SetLight(0, light);
    
    end;
    
    procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
    var
      r: TD3DRect;
    begin
      if not DXDraw.CanDraw then Exit;
    
      { Frame Movie }
      FrameMovie(GetTickCount/1000);
    
      {  Clear Screen  }
      r.x1 := 0;
      r.y1 := 0;
      r.x2 := DXDraw.SurfaceWidth;
      r.y2 := DXDraw.SurfaceHeight;
      if DXDraw.ZBuffer<>nil then
        DXDraw.D3DDevice7.Clear&#40;1, r, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, $000000, 1, 0&#41;
      else
        DXDraw.D3DDevice7.Clear&#40;1, r, D3DCLEAR_TARGET, $000000, 1, 0&#41;;
    
    
      &#123; Draw Screen &#125;
      asm
        FINIT
      end;
      AddLight;
      DXDraw.D3DDevice7.BeginScene;
    
    
      DXDraw.D3DDevice7.SetRenderState&#40;D3DRENDERSTATE_CULLMODE, Ord&#40;D3DCULL_NONE&#41;&#41;;
    
      DXDraw.D3DDevice7.SetRenderState&#40;D3DRENDERSTATE_SPECULARENABLE, 1&#41;;
      DXDraw.D3DDevice7.SetRenderState&#40;D3DRENDERSTATE_DIFFUSEMATERIALSOURCE, 0&#41;;
      DXDraw.D3DDevice7.SetRenderState&#40;D3DRENDERSTATE_LIGHTING, 1&#41;;
      DXDraw.D3DDevice7.SetRenderState&#40;D3DRENDERSTATE_SHADEMODE, 1&#41;;
      DXDraw.D3DDevice7.LightEnable&#40;0, true&#41;;
    
      DXDraw.D3DDevice7.SetRenderState&#40;D3DRENDERSTATE_AMBIENT, $A0A0A0A0&#41;;
    
      DXDraw.D3DDevice7.SetTexture&#40; 0, FTexture&#91;0&#93;.Surface.IDDSurface7&#41;;
    
      DXDraw.D3DDevice7.DrawIndexedPrimitive&#40;
        D3DPT_TRIANGLELIST, D3DFVF_VERTEX,
          g_Vertices&#91;0&#93;, 64 * 64,
            g_Indexes&#91;0&#93;, 63 * 63 * 6, 0&#41;;
    
      DXDraw.D3DDevice7.EndScene;
    
      asm
        FINIT
      end;
    
      &#123; Draw FrameRate &#125;
      with DXDraw.Surface.Canvas do
      begin
        try
          Brush.Style &#58;= bsClear;
          Font.Color &#58;= clWhite;
          Font.Size &#58;= 12;
          Textout&#40;0, 0, 'FPS&#58; '+inttostr&#40;DXTimer.FrameRate&#41;&#41;;
          if doHardware in DXDraw.NowOptions then
            Textout&#40;0, 14, 'Device&#58; Hardware'&#41;
          else
            Textout&#40;0, 14, 'Device&#58; Software'&#41;;
        finally
          Release; &#123;  Indispensability  &#125;
        end;
      end;
    
      DXDraw.Flip;
    end;
    
    procedure TMainForm.FormKeyDown&#40;Sender&#58; TObject; var Key&#58; Word;
      Shift&#58; TShiftState&#41;;
    begin
      &#123;  Application end  &#125;
      if Key=VK_ESCAPE then
        Close;
    
      &#123;  Screen mode change  &#125;
      if &#40;ssAlt in Shift&#41; and &#40;Key=VK_RETURN&#41; then
      begin
        DXDraw.Finalize;
    
        if doFullScreen in DXDraw.Options then
        begin
          RestoreWindow;
    
          DXDraw.Cursor &#58;= crDefault;
          BorderStyle &#58;= bsSizeable;
          DXDraw.Options &#58;= DXDraw.Options - &#91;doFullScreen&#93;;
        end else
        begin
          StoreWindow;
    
          DXDraw.Cursor &#58;= crNone;
          BorderStyle &#58;= bsNone;
          DXDraw.Options &#58;= DXDraw.Options + &#91;doFullScreen&#93;;
        end;
    
        DXDraw.Initialize;
      end;
    end;
    
    end.
    Last edited by Jimmy Valavanis; 30-03-2012 at 03:46 PM.

  2. #2

    DelphiX and lights in Immediate mode

    Your code seems to look fine.
    Have you tried setting DXDraw.D3DDevice7.SetRenderState(D3DRENDERSTATE_DI FFUSEMATERIALSOURCE, 1);
    IIRC - it's default state.

    PS. Cross-posting is not a good idea...
    There are only 10 types of people in this world; those who understand binary and those who don't.

  3. #3

    Thanks!!!!

    Well actually you're right that cross-posting is not a good idea...
    But I'm working on Direct3D with DelphiX for over 2 years, and I could not make lights work!!!! I was desperate....
    Until today!

    Actually,
    DXDraw.D3DDevice7.SetRenderState(D3DRENDERSTATE_DI FFUSEMATERIALSOURCE, 1);
    didn't make a difference, but motivated by your answer I did a little debugging to the return value of DXDraw.D3DDevice7.SetLight(0, light);
    And it was <> D3D_OK, it was DDERR_INVALIDPARAMS!!!
    What was wrong? Well, the wrong thing was:
    light.dvRange := D3DLIGHT_RANGE_MAX;
    I change this to
    light.dvRange := 100.0 and i work perfectly at last!

    Anyway, thanks for motivating me to solve my problem!!!
    Thanks!!!!!
    Last edited by Jimmy Valavanis; 30-03-2012 at 03:47 PM.

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
  •