{
    This file is part of Chentrah,
    Copyright (C) 2004-2008 Anton Rzheshevski (chebmaster@mail.ru).

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see http://www.gnu.org/licenses/

 **********************************************************************}


{$include mo_globaldefs.h}
{$typeinfo on}
 
unit _my_module_main;
 
interface
 
uses
   SysUtils,
   math,
   typinfo,
   mo_hub,
   chepersy,
   mo_module,
   mo_resources,
   mo_menu,
   mo_viewport;



type
  { TSkinnerModule }

  TTest16Module = class (TModule)
  protected

  public
    procedure RegisterFields; override;
    procedure OnCreate; override;
    procedure Pulse; override;
    destructor Destroy; override;
    procedure AfterLoading; override;

  end;

  TTest16ViewPort = class (TViewPort)
  protected
  public
    crapper : TStatic2dTexture;
    procedure CreateMultisamplePresentationProgram(newmls: integer); override;
    procedure RegisterFields; override;
    procedure OnResize; override;
    constructor Create(_width, _height: float); override;
    procedure RenderScene; override;
    procedure CheckRenderBuffersSizes; override;
  end;
  
// *** REQUIRED FOR INIT ROUTINE:

  MyModuleType = TTest16Module;

const
  MyModuleString = 'Chentrah Test 016';
  MyModuleVersionMajor = 0;
  MyModuleVersionMinor = 16;
  MyModuleBuildNumber = {$include build.h};
  MyInternalModuleBasePath = '_test016'; { the folder name, relative to the
                                           "modules" folder in the install path}
  MyModuleSessionSpaceLimit = 100; //megabytes


implementation



  procedure TTest16Module.OnCreate;
  var t: TTextEdit;
  begin
    inherited;

    (TBackground.Create()).AddAtBottom(Self.Control);  { missing this
      results in a nice HOM effect since the mother does *not* clear
      the color buffer assuming that the module fills it each frame
     TBackground simply renders a quad filled with standard Chentrah
       background texture thus mimicing the main app to mask the difference
       between it and the module  }

    (TTest16ViewPort.Create(1050,1050)).AddOnTop(Self.Control);

    Self.AfterLoading; //perform the same check as is used for activating new features

  end;


  procedure TTest16Module.AfterLoading;
  begin
    inherited;

   end;

  procedure TTest16Module.Pulse;
  begin
    inherited;
    // .Pulse;
  end;


  procedure TTest16Module.RegisterFields;
  begin
    RegClass(TTest16ViewPort);
	inherited;
    //ListFields(['Bryed', @self.bryed, typeinfo(TBryed)]);
  end;

  destructor TTest16Module.Destroy;
  begin
    //
    inherited;
  end;

  procedure TTest16ViewPort.RegisterFields;
  begin
    inherited;
    ListFields([
      'crapper', @crapper, typeinfo(TStatic2dtexture)
    ])
  end;

  procedure TTest16ViewPort.OnResize;
  begin
    addlog(' TViewPort.OnResize : %0x%1',[Width.Current, Height.Current]);
    inherited;
  end;

  constructor TTest16ViewPort.Create(_width, _height: float);
  begin
    inherited Create(_width, _height);
    crapper:= TStatic2dTexture.CreateFromFile(
      '*M/img/cravatar674.png', false, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
  end;

  procedure TTest16ViewPort.CheckRenderBuffersSizes;
  var
    q: qword;
    pw: integer = 0;
    ph: integer = 0;
  begin
    if Assigned(Fbo) then begin
      pw:= Fbo.Width;
      ph:= Fbo.Height;
    end;
    UsecByTsc(@q);
    inherited;
    if (pw <> Fbo.Width) or (ph <> Fbo.Height)
      then AddLog('Operation cost: %0 microseconds',[round(UsecByTsc(@q))]);
  end;

  procedure TTest16ViewPort.CreateMultisamplePresentationProgram(newmls: integer);
  var     q: qword;
  begin
    UsecByTsc(@q);
    inherited CreateMultisamplePresentationProgram(newmls);
    AddLog('Created MSAA sampler using %0 samples in %1 microseconds',[newmls, round(UsecByTsc(@q))]);
  end;

  procedure Kubik(s: float);
  begin
    s:= s/2;
    glColor3f(1, 1, 0.5);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0);  glVertex3f(-s, -s, -s);
    glTexCoord2f(0, 1);  glVertex3f(-s, s, -s);
    glColor3f(0.7, 1, 1);
    glTexCoord2f(1, 1);  glVertex3f(-s, s, s);
    glTexCoord2f(1, 0);  glVertex3f(-s, -s, s);
    glEnd;

    glColor3f(0.7, 1, 1);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0); glVertex3f(s, -s, -s);
    glTexCoord2f(0, 1); glVertex3f(s, -s, s);
    glColor3f(1, 1, 0.5);
    glTexCoord2f(1, 1); glVertex3f(s, s, s);
    glTexCoord2f(1, 0); glVertex3f(s, s, -s);
    glEnd;

    glColor3f(0.5, 1, 0.5);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0);glVertex3f(-s, -s, -s);
    glTexCoord2f(0, 1);glVertex3f(-s, -s, s);
    glColor3f(1, 0.3, 1);
    glTexCoord2f(1, 1);glVertex3f(s, -s, s);
    glTexCoord2f(1, 0);glVertex3f(s, -s, -s);
    glEnd;

    glColor3f(1, 0.3, 1);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0);glVertex3f(-s, s, -s);
    glTexCoord2f(0, 1);glVertex3f(s, s, -s);
    glColor3f(0.5, 1, 0.5);
    glTexCoord2f(1, 1);glVertex3f(s, s, s);
    glTexCoord2f(1, 0);glVertex3f(-s, s, s);
    glEnd;

    glColor3f(0.7, 0.5, 1);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0);glVertex3f(-s, -s, -s);
    glTexCoord2f(0, 1);glVertex3f(s, -s, -s);
    glColor3f(1, 0.2, 0.2);
    glTexCoord2f(1, 1);glVertex3f(s, s, -s);
    glTexCoord2f(1, 0);glVertex3f(-s, s, -s);
    glEnd;

    glColor3f(1, 0.2, 0.2);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0);glVertex3f(-s, -s, s);
    glTexCoord2f(0, 1);glVertex3f(-s, s, s);
    glColor3f(0.7, 0.5, 1);
    glTexCoord2f(1, 1);glVertex3f(s, s, s);
    glTexCoord2f(1, 0);glVertex3f(s, -s, s);
    glEnd;
  end;

   Const
     FOV = 90;
     NEARPLANE = 1;
     FARPLANE = 500;
     ASPECT = 4/3;

  procedure  TTest16ViewPort.RenderScene;
  var
    fov, s, top, bottom, left,right, aspect: float;
    qq: qword;
  begin
    ClearFbo;
    glUseProgram(0);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    fov:= 65;
    aspect:= Width.Current/Height.Current;
    top := Math.tan (FOV*3.14159/360.0)*NEARPLANE;
    bottom := -top;
    left := ASPECT*bottom;
    right := ASPECT*top;
    glFrustum (left, right, bottom, top, NEARPLANE, FARPLANE);
    glViewport(0, 0, min(renW, Fbo.Width), min(renH, Fbo.Height));
    glcolor4f(frac(Now() * 86400/3), 0, frac(Now() * 86400/5), 0.5);
    gltranslatef(0,0,-100);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glDepthMask(GL_TRUE);
    glDisable(GL_ALPHA_TEST);
    glDisable(GL_BLEND);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_FRONT);
    glEnable (GL_TEXTURE_2D);

    crapper.Bind;

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glrotatef(frac(Now() * 0.02 * 86400) * 360, 0, 1, 0);
    glrotatef(frac(Now() * 0.0033 * 86400) * 360, 1, 0, 0);
    Kubik(50);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gltranslatef(0,30,10);
    glrotatef(frac(Now() * -0.1 * 86400) * 360, 0, 1, 0);
    glrotatef(frac(Now() * -0.01 * 86400) * 360, 1, 0, 0);
    Kubik(30);
  end;

end.
