2022-03-08 12:25:51 -05:00
|
|
|
{
|
|
|
|
Apophysis Copyright (C) 2001-2004 Mark Townsend
|
|
|
|
Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
|
|
|
|
Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov
|
|
|
|
|
|
|
|
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
|
|
|
|
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
|
2022-06-23 06:22:32 -04:00
|
|
|
Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
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, write to the Free Software
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
}
|
|
|
|
unit FormRender;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
2022-06-23 06:22:32 -04:00
|
|
|
StdCtrls, ComCtrls, Math, Buttons, Registry, ExtCtrls, MMSystem,
|
2022-03-08 12:25:51 -05:00
|
|
|
System.Win.TaskbarCore, Vcl.Taskbar, Vcl.Samples.Spin, // AV
|
2022-06-23 06:22:32 -04:00
|
|
|
ControlPoint, cmap, RenderThread, RenderingInterface,
|
|
|
|
ShellAPI, ActiveX, ComObj;
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
const
|
|
|
|
{$ifdef T500}
|
|
|
|
rendersAV = 'rendersAV_250.flame';
|
|
|
|
{$else}
|
|
|
|
rendersAV = 'rendersAV.flame';
|
|
|
|
{$endif}
|
2022-06-23 06:22:32 -04:00
|
|
|
|
|
|
|
type
|
|
|
|
TWin32Version = (wvUnknown, wvWin95, wvWin98, wvWinNT, wvWin2000, wvWinXP,
|
|
|
|
wvWinVista, wvWin7, wvWinFutureFromOuterSpace);
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
type
|
|
|
|
TRenderForm = class(TForm)
|
|
|
|
btnRender: TButton;
|
|
|
|
btnCancel: TButton;
|
|
|
|
SaveDialog: TSaveDialog;
|
|
|
|
btnPause: TButton;
|
|
|
|
StatusBar: TStatusBar;
|
|
|
|
PageCtrl: TPageControl;
|
|
|
|
TabSettings: TTabSheet;
|
|
|
|
TabOutput: TTabSheet;
|
|
|
|
GroupBox5: TGroupBox;
|
|
|
|
btnSavePreset: TSpeedButton;
|
|
|
|
btnDeletePreset: TSpeedButton;
|
|
|
|
cmbPreset: TComboBox;
|
|
|
|
GroupBox2: TGroupBox;
|
|
|
|
cbWidth: TComboBox;
|
|
|
|
cbHeight: TComboBox;
|
|
|
|
GroupBox3: TGroupBox;
|
|
|
|
txtOversample: TEdit;
|
|
|
|
txtFilterRadius: TEdit;
|
|
|
|
udOversample: TUpDown;
|
|
|
|
txtDensity: TComboBox;
|
|
|
|
GroupBox4: TGroupBox;
|
|
|
|
lblApproxMem: TLabel;
|
|
|
|
lblPhysical: TLabel;
|
|
|
|
lblMaxbits: TLabel;
|
|
|
|
Label9: TLabel;
|
|
|
|
cbMaxMemory: TComboBox;
|
|
|
|
chkLimitMem: TCheckBox;
|
|
|
|
Output: TMemo;
|
|
|
|
lblMemory: TLabel;
|
|
|
|
btnBrowse: TSpeedButton;
|
|
|
|
txtFilename: TEdit;
|
|
|
|
GroupBox1: TGroupBox;
|
|
|
|
chkSave: TCheckBox;
|
|
|
|
GroupBox6: TGroupBox;
|
|
|
|
chkPostProcess: TCheckBox;
|
|
|
|
chkShutdown: TCheckBox;
|
|
|
|
btnGoTo: TSpeedButton;
|
|
|
|
pnlWidth: TPanel;
|
|
|
|
pnlHeight: TPanel;
|
|
|
|
pnlDensity: TPanel;
|
|
|
|
pnlFilter: TPanel;
|
|
|
|
pnlOversample: TPanel;
|
|
|
|
pnlLimit: TPanel;
|
|
|
|
pnlTarget: TPanel;
|
|
|
|
btnDonate: TButton;
|
|
|
|
btnSaveLog: TButton;
|
|
|
|
chkBinary: TCheckBox;
|
|
|
|
ProgressBar2: TProgressBar;
|
|
|
|
PBMem: TProgressBar;
|
|
|
|
chkSaveIncompleteRenders: TCheckBox;
|
|
|
|
lblCPUCores: TLabel;
|
|
|
|
cbAspectRatio: TComboBox;
|
|
|
|
chkEmbedFlame: TCheckBox;
|
|
|
|
chkPlaySound: TCheckBox;
|
|
|
|
btnSnapshot: TButton;
|
|
|
|
ProgressTaskbar: TTaskbar;
|
|
|
|
sbFilterRadius: TSpinButton;
|
2022-06-23 06:22:32 -04:00
|
|
|
lblRatio: TPanel;
|
2022-03-08 12:25:51 -05:00
|
|
|
procedure btnSaveLogClick(Sender: TObject);
|
|
|
|
procedure btnDonateClick(Sender: TObject);
|
|
|
|
procedure cbMaxMemoryChange(Sender: TObject);
|
|
|
|
procedure FormCreate(Sender: TObject);
|
|
|
|
procedure FormDestroy(Sender: TObject);
|
|
|
|
procedure btnRenderClick(Sender: TObject);
|
|
|
|
procedure FormShow(Sender: TObject);
|
|
|
|
procedure txtWidthChange(Sender: TObject);
|
|
|
|
procedure txtHeightChange(Sender: TObject);
|
|
|
|
procedure txtOversampleChange(Sender: TObject);
|
|
|
|
procedure txtFilenameChange(Sender: TObject);
|
|
|
|
procedure btnCancelClick(Sender: TObject);
|
|
|
|
procedure txtDensityChange(Sender: TObject);
|
|
|
|
procedure txtFilterRadiusExit(Sender: TObject);
|
|
|
|
procedure FormClose(Sender: TObject; var Action: TCloseAction);
|
|
|
|
procedure btnPauseClick(Sender: TObject);
|
|
|
|
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
|
|
|
|
procedure btnSavePresetClick(Sender: TObject);
|
|
|
|
procedure btnBrowseClick(Sender: TObject);
|
|
|
|
procedure btnDeletePresetClick(Sender: TObject);
|
|
|
|
procedure cmbPresetChange(Sender: TObject);
|
|
|
|
//procedure chkMaintainClick(Sender: TObject);
|
|
|
|
procedure chkSaveIncompleteRendersClick(Sender: TObject);
|
|
|
|
procedure btnGoToClick(Sender: TObject);
|
|
|
|
procedure cbAspectRatioChange(Sender: TObject);
|
|
|
|
procedure chkPlaySoundClick(Sender: TObject);
|
|
|
|
procedure FormActivate(Sender: TObject);
|
|
|
|
procedure btnSnapshotClick(Sender: TObject);
|
|
|
|
procedure NumFieldKeyPress(Sender: TObject; var Key: Char);
|
|
|
|
procedure sbFilterRadiusUpClick(Sender: TObject);
|
|
|
|
procedure sbFilterRadiusDownClick(Sender: TObject);
|
|
|
|
procedure txtDensityExit(Sender: TObject);
|
|
|
|
procedure cbWidthExit(Sender: TObject);
|
|
|
|
procedure cbHeightExit(Sender: TObject);
|
2022-06-23 06:22:32 -04:00
|
|
|
procedure ProgressTaskbarThumbButtonClick(Sender: TObject;
|
|
|
|
AButtonID: Integer);
|
2022-03-08 12:25:51 -05:00
|
|
|
private
|
|
|
|
StartTime, EndTime, oldElapsed, edt: TDateTime;
|
|
|
|
oldProg: double;
|
2022-06-23 06:22:32 -04:00
|
|
|
PhysicalMemory, ApproxMemory, TotalPhysicalMemory: int64;
|
2022-03-08 12:25:51 -05:00
|
|
|
ApproxSamples: int64;
|
|
|
|
|
|
|
|
procedure DoPostProcess;
|
|
|
|
|
|
|
|
procedure HandleThreadCompletion(var Message: TMessage);
|
|
|
|
message WM_THREAD_COMPLETE;
|
|
|
|
procedure HandleThreadTermination(var Message: TMessage);
|
|
|
|
message WM_THREAD_TERMINATE;
|
|
|
|
procedure ListPresets;
|
|
|
|
function WindowsExit(RebootParam: Longword = EWX_POWEROFF or EWX_FORCE): Boolean;
|
|
|
|
procedure Save(const str: string);
|
2022-06-23 06:22:32 -04:00
|
|
|
function IsLimitingMemory(): boolean;
|
|
|
|
procedure OnProgress(prog: double);
|
|
|
|
procedure ShowMemoryStatus;
|
2022-03-08 12:25:51 -05:00
|
|
|
public
|
|
|
|
Renderer: TRenderThread;
|
2022-06-23 06:22:32 -04:00
|
|
|
|
|
|
|
//ColorMap: TColorMap;
|
2022-03-08 12:25:51 -05:00
|
|
|
cp: TControlPoint;
|
|
|
|
Filename: string;
|
|
|
|
ImageWidth, ImageHeight, Oversample: Integer;
|
2022-06-23 06:22:32 -04:00
|
|
|
Sample_Density, Filter_Radius: double;
|
2022-03-08 12:25:51 -05:00
|
|
|
MaxMemory: integer;
|
|
|
|
bRenderAll: boolean;
|
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
RenderFlameFile: string; // AV
|
|
|
|
FlameNames: array of string; // AV
|
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
procedure ResetControls;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function GetCpuCount: integer; // AV: this is used in Options
|
2022-06-23 06:22:32 -04:00
|
|
|
function GetWinVersion: TWin32Version; // AV: moved from Main
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
var
|
|
|
|
RenderForm: TRenderForm;
|
|
|
|
Ratio: double;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
2022-06-23 06:22:32 -04:00
|
|
|
Main, Global, SavePreset, formPostProcess, ImageMaker, Tracer, Translation;
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
{$R *.DFM}
|
|
|
|
|
|
|
|
function TRenderForm.IsLimitingMemory():boolean;
|
|
|
|
begin
|
|
|
|
Result := (cbMaxMemory.ItemIndex > 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.ResetControls;
|
|
|
|
begin
|
|
|
|
txtFilename.Enabled := true;
|
|
|
|
btnBrowse.Enabled := true;
|
|
|
|
cbWidth.Enabled := true;
|
|
|
|
cbHeight.Enabled := true;
|
|
|
|
txtDensity.Enabled := true;
|
|
|
|
txtFilterRadius.enabled := true;
|
|
|
|
txtOversample.Enabled := true;
|
|
|
|
//chkLimitMem.Enabled := true;
|
|
|
|
cbMaxMemory.enabled := true;
|
|
|
|
chkPostProcess.Enabled := not IsLimitingMemory;
|
|
|
|
chkSaveIncompleteRenders.Enabled := not IsLimitingMemory;
|
|
|
|
btnRender.Enabled := true;
|
|
|
|
cmbPreset.enabled := true;
|
|
|
|
btnSaveLog.Enabled := false;
|
|
|
|
chkSave.enabled := true;
|
|
|
|
chkPostProcess.enabled := true;
|
|
|
|
chkShutdown.enabled := true;
|
|
|
|
btnSavePreset.enabled := true;
|
|
|
|
btnDeletePreset.enabled := true;
|
|
|
|
btnCancel.Caption := TextByKey('common-close');
|
|
|
|
btnPause.enabled := false;
|
|
|
|
//chkMaintain.Enabled := true;
|
|
|
|
cbAspectRatio.Enabled := true; // AV
|
|
|
|
btnSnapshot.Visible := false; // AV
|
|
|
|
|
|
|
|
ProgressBar2.Position := 0;
|
|
|
|
ProgressTaskBar.ProgressValue := 0; // AV
|
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
|
|
|
|
|
|
|
|
pnlWidth.Enabled := true;
|
|
|
|
pnlHeight.Enabled := true;
|
|
|
|
pnlDensity.Enabled := true;
|
|
|
|
pnlFilter.Enabled := true;
|
|
|
|
pnlOversample.Enabled := true;
|
|
|
|
pnlLimit.Enabled := true;
|
|
|
|
pnlTarget.Enabled := true;
|
|
|
|
|
|
|
|
pnlWidth.Font.Color := clWindowText;
|
|
|
|
pnlHeight.Font.Color := clWindowText;
|
|
|
|
pnlDensity.Font.Color := clWindowText;
|
|
|
|
pnlFilter.Font.Color := clWindowText;
|
|
|
|
pnlOversample.Font.Color := clWindowText;
|
|
|
|
pnlLimit.Font.Color := clWindowText;
|
|
|
|
pnlTarget.Font.Color := clWindowText;
|
|
|
|
ShowMemoryStatus;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function GetCpuCount: integer;
|
|
|
|
var
|
|
|
|
si: TSystemInfo;
|
|
|
|
begin;
|
|
|
|
GetSystemInfo(si);
|
|
|
|
Result := si.dwNumberOfProcessors;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.ShowMemoryStatus;
|
|
|
|
var
|
|
|
|
GlobalMemoryInfo: TMemoryStatus; // holds the global memory status information
|
|
|
|
begin
|
|
|
|
GlobalMemoryInfo.dwLength := SizeOf(GlobalMemoryInfo);
|
|
|
|
GlobalMemoryStatus(GlobalMemoryInfo);
|
|
|
|
PhysicalMemory := GlobalMemoryInfo.dwAvailPhys div 1048576;
|
|
|
|
TotalPhysicalMemory := GlobalMemoryInfo.dwTotalPhys div 1048576;
|
|
|
|
//TotalPhysicalMemory := TotalPhysicalMemory * 9 div 10; // assume that OS will take 10% of RAM ;)
|
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
{$ifdef CPUX86}
|
|
|
|
ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 16 div 1048576;
|
|
|
|
{$else}
|
|
|
|
ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 32 div 1048576;
|
|
|
|
{$endif}
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
lblMemory.Caption := Format(TextByKey('render-resourceusage-infotext'), [ApproxMemory, PhysicalMemory]);
|
|
|
|
PBMem.Position := round(100 * (ApproxMemory / PhysicalMemory));
|
|
|
|
|
|
|
|
if ApproxMemory > PhysicalMemory then // AV: adapted for GUI styles
|
|
|
|
begin
|
|
|
|
// AV: exclude the style for the font to set its color properly
|
|
|
|
lblMemory.StyleElements := [seClient, seBorder];
|
|
|
|
lblMemory.Font.Color := clRed;
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
lblMemory.StyleElements := [seClient, seBorder, seFont];
|
|
|
|
lblMemory.Font.Color := clWindowText;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if NrTreads > GetCpuCount then NrTreads := GetCpuCount; // AV: only actual Nrs
|
|
|
|
{
|
|
|
|
lblCpuCores.Font.Color := clRed
|
|
|
|
else
|
|
|
|
lblCpuCores.Font.Color := clWindowText;
|
|
|
|
}
|
|
|
|
|
|
|
|
lblCPUCores.Caption := Format(TextByKey('render-resourceusage-infotext2'), [NrTreads, GetCpuCount]);
|
|
|
|
//btnRender.Enabled := (ApproxMemory <= PhysicalMemory) or (cbMaxMemory.ItemIndex > 0);
|
|
|
|
|
|
|
|
if ApproxMemory > 0 then
|
|
|
|
lblMaxbits.caption := format('%2.3f', [8 + log2(
|
|
|
|
sample_density * sqr(power(2, cp.zoom)) * int64(ImageHeight) * int64(ImageWidth) / sqr(oversample)
|
|
|
|
)]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure Trace2(const str: string);
|
|
|
|
begin
|
|
|
|
if TraceLevel >= 2 then
|
|
|
|
RenderForm.Output.Lines.Add('. . ' + str);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.Save(const str:string);
|
|
|
|
begin
|
|
|
|
Renderer.SaveImage(FileName);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.sbFilterRadiusDownClick(Sender: TObject); // AV
|
|
|
|
var n: double;
|
|
|
|
begin
|
|
|
|
try
|
|
|
|
n := StrToFloat(txtFilterRadius.Text);
|
|
|
|
n := RoundTo(n - 0.05, -3);
|
|
|
|
if (n > 0) then
|
|
|
|
txtFilterRadius.Text := FloatToStr(n);
|
|
|
|
except
|
|
|
|
raise Exception.Create(TextByKey('render-status-invalidfilterradius'));
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.sbFilterRadiusUpClick(Sender: TObject); // AV
|
|
|
|
var n: double;
|
|
|
|
begin
|
|
|
|
try
|
|
|
|
n := StrToFloat(txtFilterRadius.Text);
|
|
|
|
txtFilterRadius.Text := Format('%.3g', [n + 0.05]);
|
|
|
|
except
|
|
|
|
raise Exception.Create(TextByKey('render-status-invalidfilterradius'));
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.HandleThreadCompletion(var Message: TMessage);
|
|
|
|
var
|
|
|
|
tryAgain: boolean;
|
|
|
|
begin
|
|
|
|
Trace2(MsgComplete + IntToStr(message.LParam));
|
|
|
|
if not assigned(Renderer) then begin
|
|
|
|
Trace2(MsgNotAssigned);
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
if Renderer.ThreadID <> message.LParam then begin
|
|
|
|
Trace2(MsgAnotherRunning);
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
|
|
|
|
EndTime := Now;
|
|
|
|
|
|
|
|
repeat
|
|
|
|
tryAgain := false;
|
|
|
|
try
|
|
|
|
Save(FileName);
|
|
|
|
if ShowRenderImage then // AV
|
|
|
|
if FileExists(FileName) then
|
|
|
|
ShellExecute(Application.handle, PChar('open'),
|
|
|
|
PChar(ExtractFileName(FileName)), nil, PChar(renderPath),
|
|
|
|
SW_SHOWNORMAL);
|
|
|
|
except
|
|
|
|
on e: Exception do begin
|
|
|
|
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-saveerror-log'));
|
|
|
|
tryAgain := (Application.MessageBox(PChar(TextByKey('render-status-saveerror-message1') + #13#10 + e.Message +
|
2022-06-23 06:22:32 -04:00
|
|
|
#13#10 + TextByKey('render-status-saveerror-message2')), ApophysisSVN, MB_RETRYCANCEL or MB_ICONERROR) = IDRETRY);
|
2022-03-08 12:25:51 -05:00
|
|
|
// AV: displaying status in red
|
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.Error;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
until tryAgain = false;
|
|
|
|
|
|
|
|
if PlaySoundOnRenderComplete then
|
|
|
|
if RenderCompleteSoundFile <> '' then
|
|
|
|
sndPlaySound(PChar(RenderCompleteSoundFile), SND_FILENAME or SND_NOSTOP or SND_ASYNC)
|
|
|
|
else
|
|
|
|
sndPlaySound(pchar(SND_ALIAS_SYSTEMASTERISK), SND_ALIAS_ID or SND_NOSTOP or SND_ASYNC);
|
|
|
|
|
|
|
|
PageCtrl.TabIndex := 1;
|
|
|
|
if ShowRenderStats then
|
|
|
|
Renderer.ShowBigStats
|
|
|
|
else
|
|
|
|
Renderer.ShowSmallStats;
|
|
|
|
Output.Lines.Add(' ' + TextByKey('render-status-totaltime') + TimeToString(EndTime - StartTime));
|
|
|
|
Output.Lines.Add('');
|
|
|
|
|
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
|
|
|
|
|
|
|
|
if not IsLimitingMemory and chkPostProcess.checked then
|
|
|
|
DoPostProcess;
|
|
|
|
|
|
|
|
Renderer.Free;
|
|
|
|
Renderer := nil;
|
|
|
|
if not bRenderAll then ResetControls;
|
|
|
|
|
|
|
|
btnSaveLog.Enabled := true;
|
|
|
|
|
|
|
|
if chkShutdown.Checked and not bRenderAll then
|
|
|
|
WindowsExit;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.HandleThreadTermination(var Message: TMessage);
|
|
|
|
begin
|
|
|
|
Trace2(MsgTerminated + IntToStr(message.LParam));
|
|
|
|
if not assigned(Renderer) then begin
|
|
|
|
Trace2(MsgNotAssigned);
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
if Renderer.ThreadID <> message.LParam then begin
|
|
|
|
Trace2(MsgAnotherRunning);
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
{
|
|
|
|
// AV: temporary commented out since undestroyed TBaseRenderer objects
|
|
|
|
// from Renderer.GetRenderer method cause regular large memory leaks!
|
|
|
|
|
|
|
|
if Renderer.GetRenderer.Hibernated then
|
|
|
|
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-renderhibernated'))
|
|
|
|
else }
|
|
|
|
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-renderterminated'));
|
2022-06-23 06:22:32 -04:00
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
Output.Lines.Add('');
|
|
|
|
|
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
|
|
|
|
|
|
|
|
sndPlaySound(pchar(SND_ALIAS_SYSTEMEXCLAMATION), SND_ALIAS_ID or SND_NOSTOP or SND_ASYNC);
|
|
|
|
|
|
|
|
PageCtrl.TabIndex := 0; // AV: moved from btnCancelClick
|
|
|
|
|
|
|
|
Renderer.Free;
|
|
|
|
Renderer := nil;
|
|
|
|
ResetControls;
|
|
|
|
|
|
|
|
btnSaveLog.Enabled := true;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.OnProgress(prog: double);
|
|
|
|
var
|
|
|
|
Elapsed, Remaining, dt: TDateTime;
|
|
|
|
begin
|
|
|
|
Elapsed := Now - StartTime;
|
|
|
|
dt := Elapsed - oldElapsed;
|
|
|
|
if (prog = 1.0) then begin
|
|
|
|
StatusBar.Panels[0].text := Format(TextByKey('render-status-elapsed') + ': %2.2d:%2.2d:%2.2d.%2.2d',
|
|
|
|
[Trunc(Elapsed * 24),
|
|
|
|
Trunc(Elapsed * 24 * 60) mod 60,
|
|
|
|
Trunc(Elapsed * 24 * 60 * 60) mod 60,
|
|
|
|
Trunc(Elapsed * 24 * 60 * 60 * 100) mod 100]);
|
|
|
|
StatusBar.Panels[1].text := TextByKey('render-status-remaining') + ': 00:00:00.00';
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
|
|
|
|
//if (dt < 1/24/60/60/10) then exit;
|
|
|
|
if (dt < 1/24/60/60) then exit; // PB: too much time consuming... was every 1/10th seconds!
|
|
|
|
oldElapsed := Elapsed;
|
|
|
|
|
|
|
|
prog := (Renderer.Slice + Prog) / Renderer.NrSlices;
|
|
|
|
if ShowProgress then begin
|
2022-06-23 06:22:32 -04:00
|
|
|
ProgressBar2.Position := round(100 * prog);
|
|
|
|
// AV: to display the progress on the taskbar
|
|
|
|
//ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal; // AV
|
|
|
|
ProgressTaskBar.ProgressValue := ProgressBar2.Position; // AV
|
2022-03-08 12:25:51 -05:00
|
|
|
end;
|
|
|
|
|
|
|
|
StatusBar.Panels[0].text := Format(TextByKey('render-status-elapsed') + ': %2.2d:%2.2d:%2.2d.%2.2d',
|
|
|
|
[Trunc(Elapsed * 24),
|
|
|
|
Trunc(Elapsed * 24 * 60) mod 60,
|
|
|
|
Trunc(Elapsed * 24 * 60 * 60) mod 60,
|
|
|
|
Trunc(Elapsed * 24 * 60 * 60 * 100) mod 100]);
|
|
|
|
|
|
|
|
edt := edt + dt;
|
|
|
|
if (edt > 1/24/60/60/2) and (prog > 0) then
|
|
|
|
begin
|
|
|
|
Remaining := (1 - prog) * edt / (prog - oldProg);
|
|
|
|
edt := 0;
|
|
|
|
oldProg := prog;
|
|
|
|
|
|
|
|
StatusBar.Panels[1].text := Format(TextByKey('render-status-remaining') + ': %2.2d:%2.2d:%2.2d.%2.2d',
|
|
|
|
[Trunc(Remaining * 24),
|
|
|
|
Trunc(Remaining * 24 * 60) mod 60,
|
|
|
|
Trunc(Remaining * 24 * 60 * 60) mod 60,
|
|
|
|
Trunc(Remaining * 24 * 60 * 60 * 100) mod 100]);
|
|
|
|
end;
|
|
|
|
StatusBar.Panels[2].text := Format(TextByKey('render-status-slicestatus'), [(Renderer.Slice + 1), (Renderer.nrSlices)]);
|
2022-06-23 06:22:32 -04:00
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
Application.ProcessMessages;
|
|
|
|
end;
|
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
procedure TRenderForm.ProgressTaskbarThumbButtonClick(Sender: TObject;
|
|
|
|
AButtonID: Integer);
|
|
|
|
begin
|
|
|
|
if AButtonID = 0 then
|
|
|
|
begin
|
|
|
|
if Assigned(Renderer) and (not bRenderAll) then begin
|
|
|
|
if Renderer.Suspended = false then
|
|
|
|
begin
|
|
|
|
Renderer.Suspend;
|
|
|
|
btnSnapshotClick(Sender);
|
|
|
|
Renderer.Resume;
|
|
|
|
end else
|
|
|
|
btnSnapshotClick(Sender);
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
btnCancelClick(Sender);
|
|
|
|
end;
|
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
procedure TRenderForm.FormCreate(Sender: TObject);
|
|
|
|
begin
|
2022-06-23 06:22:32 -04:00
|
|
|
{$ifdef CPUX64}
|
2022-03-08 12:25:51 -05:00
|
|
|
cbMaxMemory.Items.Add('2048');
|
|
|
|
cbMaxMemory.Items.Add('3072');
|
|
|
|
cbMaxMemory.Items.Add('4096');
|
|
|
|
{$endif}
|
|
|
|
|
|
|
|
pnlWidth.Caption := TextByKey('common-width');
|
|
|
|
pnlHeight.Caption := TextByKey('common-height');
|
|
|
|
GroupBox2.Caption := TextByKey('common-size');
|
|
|
|
cbAspectRatio.Items[0] := TextByKey('adjustment-tab-size-custom'); // AV
|
|
|
|
cbAspectRatio.Items[1] := TextByKey('common-keepaspect'); // AV
|
|
|
|
lblRatio.Caption := TextByKey('adjustment-tab-size-ratio'); // AV
|
|
|
|
pnlTarget.Caption := TextByKey('common-destination');
|
|
|
|
btnBrowse.Hint := TextByKey('common-browse');
|
|
|
|
GroupBox3.Caption := TextByKey('common-quality');
|
|
|
|
pnlFilter.Caption := TextByKey('common-filterradius');
|
|
|
|
pnlDensity.Caption := TextByKey('common-density');
|
|
|
|
pnlOversample.Caption := TextByKey('common-oversample');
|
|
|
|
btnRender.Caption := TextByKey('common-start');
|
|
|
|
btnPause.Caption := TextByKey('common-pause');
|
|
|
|
btnCancel.Caption := TextByKey('common-close');
|
|
|
|
self.Caption := TextByKey('render-title');
|
2022-06-23 06:22:32 -04:00
|
|
|
self.Hint := self.Caption; // AV: hack
|
2022-03-08 12:25:51 -05:00
|
|
|
TabSettings.Caption := TextByKey('render-tab-settings-title');
|
|
|
|
TabOutput.Caption := TextByKey('render-tab-output-title');
|
|
|
|
btnGoTo.Hint := TextByKey('render-common-gotofolder');
|
|
|
|
GroupBox4.Caption := TextByKey('render-resourceusage-title');
|
|
|
|
pnlLimit.Caption := TextByKey('render-resourceusage-limit');
|
|
|
|
chkSave.Caption := TextByKey('render-output-saveparams1');
|
|
|
|
chkEmbedFlame.Caption := TextByKey('render-output-saveparams2');
|
|
|
|
GroupBox6.Caption := TextByKey('render-completion-title');
|
|
|
|
chkPostProcess.Caption := TextByKey('render-completion-postprocess');
|
|
|
|
chkShutdown.Caption := TextByKey('render-completion-shutdown');
|
|
|
|
chkPlaySound.Caption := TextByKey('render-completion-playsound');
|
|
|
|
chkSaveIncompleteRenders.Caption := TextByKey('render-completion-saveincomplete');
|
|
|
|
cbMaxMemory.Items[0] := TextByKey('render-resourceusage-nolimit') ;
|
|
|
|
Groupbox1.Caption := TextByKey('render-output-title');
|
|
|
|
Groupbox5.Caption := TextByKey('render-presets-title');
|
|
|
|
btnSavePreset.Hint := TextByKey('render-presets-save');
|
|
|
|
btnDeletePreset.Hint := TextByKey('render-presets-delete');
|
|
|
|
btnDonate.Caption := TextByKey('common-donate');
|
|
|
|
btnDonate.Hint := TextByKey('common-donatehint');
|
|
|
|
btnSnapshot.Caption := TextByKey('render-status-dosnapshot'); // AV
|
|
|
|
btnSnapshot.Hint := TextByKey('render-status-dosnapshothint');
|
2022-06-23 06:22:32 -04:00
|
|
|
ProgressTaskbar.TaskbarButtons[1].Hint := TextByKey('render-status-stop');
|
|
|
|
ProgressTaskbar.TaskbarButtons[0].Hint := TextByKey('render-status-showimage');
|
|
|
|
|
|
|
|
// AV: fixed the filter order and moved this here since it never changes
|
|
|
|
SaveDialog.Filter := Format('%s|*.bmp;*.dib|%s|*.png|%s|*.jpg;*.jpeg|%s|*.bmp;*.dib;*.jpg;*.jpeg;*.png',
|
|
|
|
[TextByKey('common-filter-bitmap'), TextByKey('common-filter-png'),
|
|
|
|
TextByKey('common-filter-jpeg'), TextByKey('common-filter-allimages')]);
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
cp := TControlPoint.Create;
|
|
|
|
cbMaxMemory.ItemIndex := 0;
|
|
|
|
cbAspectRatio.ItemIndex := 1; // AV
|
2022-06-23 06:22:32 -04:00
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
MainForm.Buttons.GetBitmap(2, btnSavePreset.Glyph);
|
|
|
|
// MainForm.Buttons.GetBitmap(9, btnDeletePreset.Glyph);
|
|
|
|
bRenderAll := false;
|
|
|
|
ListPresets;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.FormDestroy(Sender: TObject);
|
|
|
|
begin
|
|
|
|
if assigned(Renderer) then begin
|
|
|
|
Renderer.Terminate;
|
|
|
|
Renderer.WaitFor;
|
|
|
|
Renderer.Free;
|
|
|
|
end;
|
|
|
|
cp.free;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.NumFieldKeyPress(Sender: TObject; var Key: Char); // AV
|
|
|
|
var cs: TSysCharSet;
|
|
|
|
begin
|
|
|
|
cs := ['0'..'9', #8];
|
|
|
|
if Sender = txtFilterRadius then
|
|
|
|
begin
|
|
|
|
if (Key = ',') then Key := '.';
|
|
|
|
include(cs, '.');
|
|
|
|
end;
|
|
|
|
if not CharInSet(Key, cs) then Key:= #0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.btnRenderClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
iCurrFlame: integer;
|
2022-06-23 06:22:32 -04:00
|
|
|
t, ext: string;
|
|
|
|
lim: integer;
|
|
|
|
ilm: boolean;
|
2022-03-08 12:25:51 -05:00
|
|
|
{ sl: TStringList;
|
|
|
|
tryAgain: boolean;
|
|
|
|
cancel: boolean;
|
|
|
|
result: integer; }
|
|
|
|
begin
|
|
|
|
// overwrite target with 0b file
|
|
|
|
// this to test writability in output directory
|
|
|
|
{sl := TStringList.Create;
|
|
|
|
sl.Text := '';
|
|
|
|
repeat
|
|
|
|
tryAgain := false;
|
|
|
|
cancel := false;
|
|
|
|
try
|
|
|
|
sl.SaveToFile(txtFileName.Text);
|
|
|
|
except
|
|
|
|
on e: Exception do begin
|
|
|
|
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-saveerror-log'));
|
|
|
|
result := (Application.MessageBox(PChar(TextByKey('render-status-saveerror-message1') + #13#10 + e.Message +
|
2022-06-23 06:22:32 -04:00
|
|
|
#13#10 + TextByKey('render-status-saveerror-message2')), ApophysisSVN, MB_RETRYCANCEL or MB_ICONERROR));
|
2022-03-08 12:25:51 -05:00
|
|
|
tryAgain := (result = IDRETRY);
|
|
|
|
cancel := (result = IDCANCEL);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
until (tryAgain = false) or (cancel = true);
|
|
|
|
sl.Destroy; }
|
|
|
|
|
|
|
|
//if (cancel) then Exit;
|
|
|
|
Output.Text := '';
|
|
|
|
|
|
|
|
ImageWidth := StrToInt(cbWidth.text);
|
|
|
|
ImageHeight := StrToInt(cbHeight.text);
|
|
|
|
|
|
|
|
ilm := IsLimitingMemory;
|
|
|
|
if (IsLimitingMemory) then begin
|
|
|
|
lim := StrToInt(cbMaxMemory.text);
|
|
|
|
MaxMemory := lim;
|
|
|
|
end
|
|
|
|
else lim := PhysicalMemory + 1;
|
|
|
|
|
|
|
|
if not ilm then begin
|
|
|
|
if (ApproxMemory > {Total}PhysicalMemory) then
|
|
|
|
begin
|
2022-06-23 06:22:32 -04:00
|
|
|
if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory1')),
|
|
|
|
ApophysisSVN, MB_ICONWARNING or MB_YESNO) then exit;
|
2022-03-08 12:25:51 -05:00
|
|
|
end;
|
|
|
|
end
|
|
|
|
else if (PhysicalMemory < lim) and (Approxmemory > PhysicalMemory) then begin
|
2022-06-23 06:22:32 -04:00
|
|
|
if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory2')),
|
|
|
|
ApophysisSVN, MB_ICONWARNING or MB_YESNO) then exit;
|
2022-03-08 12:25:51 -05:00
|
|
|
end;
|
|
|
|
|
|
|
|
t := txtFilename.Text;
|
2022-06-23 06:22:32 -04:00
|
|
|
if t = '' then begin
|
|
|
|
Application.MessageBox(PChar(TextByKey('render-status-nofilename')), ApophysisSVN, 48);
|
|
|
|
exit;
|
2022-03-08 12:25:51 -05:00
|
|
|
end;
|
2022-06-23 06:22:32 -04:00
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
if FileExists(t) then
|
2022-06-23 06:22:32 -04:00
|
|
|
if Application.MessageBox(PChar(Format(TextByKey('render-status-fileexists-message1'),
|
|
|
|
[t]) + #13#10 + TextByKey('render-status-fileexists-message2')),
|
|
|
|
ApophysisSVN, 52) = ID_NO then exit;
|
2022-03-08 12:25:51 -05:00
|
|
|
if not DirectoryExists(ExtractFileDir(t)) then
|
|
|
|
raise Exception.Create(TextByKey('render-status-pathdoesnotexist')); // AV
|
|
|
|
|
|
|
|
{Check for invalid values }
|
|
|
|
{ AV: all MessageBoxes replaced by raised Exceptions for speed }
|
|
|
|
if (sample_density <= 0) then
|
|
|
|
raise Exception.Create(TextByKey('render-status-invaliddensity')); // AV
|
|
|
|
|
|
|
|
if filter_radius <= 0 then
|
|
|
|
raise Exception.Create(TextByKey('render-status-invalidfilterradius')); // AV
|
|
|
|
{
|
|
|
|
// AV: how is it possible, if (udOversample.Min = 1) and (txtOversample.ReadOnly = true)?
|
|
|
|
if Oversample < 1 then
|
2022-06-23 06:22:32 -04:00
|
|
|
raise Exception.Create(TextByKey('render-status-invalidoversample'));
|
2022-03-08 12:25:51 -05:00
|
|
|
}
|
|
|
|
if ImageWidth < 1 then
|
|
|
|
raise Exception.Create(TextByKey('render-status-invalidwidth')); // AV
|
|
|
|
|
|
|
|
if ImageHeight < 1 then
|
|
|
|
raise Exception.Create(TextByKey('render-status-invalidheight')); // AV
|
|
|
|
|
|
|
|
if (ilm) then
|
|
|
|
if lim * 1024*1024 < ImageWidth * (int64(ImageHeight) * 4 + oversample) then begin
|
|
|
|
// Must be enough memory to hold the final image (RGBA)
|
2022-06-23 06:22:32 -04:00
|
|
|
if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-maxmemorytoosmall')),
|
|
|
|
ApophysisSVN, MB_ICONERROR or MB_YESNO) then exit;
|
2022-03-08 12:25:51 -05:00
|
|
|
end;
|
|
|
|
|
|
|
|
// AV: activate the taskbar progress
|
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal; // AV
|
2022-06-23 06:22:32 -04:00
|
|
|
ProgressTaskBar.ProgressValue := 0; // AV
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
txtFilename.Enabled := false;
|
|
|
|
btnBrowse.Enabled := false;
|
|
|
|
cbWidth.Enabled := False;
|
|
|
|
cbHeight.Enabled := false;
|
|
|
|
txtDensity.Enabled := false;
|
|
|
|
txtFilterRadius.enabled := false;
|
|
|
|
txtOversample.Enabled := false;
|
|
|
|
//chkLimitMem.Enabled := true;
|
|
|
|
cbMaxMemory.Enabled := false;
|
|
|
|
cmbPreset.enabled := false;
|
|
|
|
chkSave.enabled := false;
|
|
|
|
chkPostProcess.enabled := false;
|
|
|
|
chkShutdown.enabled := false;
|
|
|
|
btnSavePreset.enabled := false;
|
|
|
|
btnDeletePreset.enabled := false;
|
|
|
|
btnRender.Enabled := false;
|
|
|
|
btnSaveLog.Enabled := false;
|
|
|
|
btnPause.enabled := true;
|
|
|
|
btnCancel.Caption := TextByKey('common-cancel');
|
|
|
|
//chkMaintain.Enabled := false;
|
|
|
|
cbAspectRatio.Enabled := False;
|
|
|
|
StartTime := Now;
|
|
|
|
|
|
|
|
pnlWidth.Enabled := false;
|
|
|
|
pnlHeight.Enabled := false;
|
|
|
|
pnlDensity.Enabled := false;
|
|
|
|
pnlFilter.Enabled := false;
|
|
|
|
pnlOversample.Enabled := false;
|
|
|
|
pnlLimit.Enabled := false;
|
|
|
|
pnlTarget.Enabled := false;
|
|
|
|
|
|
|
|
pnlWidth.Font.Color := clGrayText;
|
|
|
|
pnlHeight.Font.Color := clGrayText;
|
|
|
|
pnlDensity.Font.Color := clGrayText;
|
|
|
|
pnlFilter.Font.Color := clGrayText;
|
|
|
|
pnlOversample.Font.Color := clGrayText;
|
|
|
|
pnlLimit.Font.Color := clGrayText;
|
|
|
|
pnlTarget.Font.Color := clGrayText;
|
|
|
|
|
|
|
|
PageCtrl.TabIndex := 1;
|
|
|
|
|
|
|
|
if Output.Lines.Count >= 1000 then Output.Lines.Clear;
|
|
|
|
|
|
|
|
if bRenderAll then
|
|
|
|
begin
|
2022-06-23 06:22:32 -04:00
|
|
|
renderPath := ExtractFilePath(FileName); // AV
|
|
|
|
ext := ExtractFileExt(FileName); // AV
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
if Assigned(Renderer) then begin
|
|
|
|
Output.Lines.Add(TimeToStr(Now) + TextByKey('render-status-shuttingdownrender'));
|
|
|
|
Renderer.Terminate;
|
|
|
|
Renderer.WaitFor;
|
|
|
|
Renderer.Free;
|
|
|
|
Renderer := nil;
|
|
|
|
end;
|
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
for iCurrFlame := 0 to High(FlameNames) {MainForm.ListView1.Items.Count-1} do
|
2022-03-08 12:25:51 -05:00
|
|
|
begin
|
2022-06-23 06:22:32 -04:00
|
|
|
{
|
2022-03-08 12:25:51 -05:00
|
|
|
MainForm.ListView1.ItemIndex := iCurrFlame;
|
|
|
|
cp.Free;
|
|
|
|
cp := TControlPoint.Create;
|
|
|
|
cp.Copy(MainCP);
|
|
|
|
cp.cmap := maincp.cmap;
|
|
|
|
zoom := maincp.zoom;
|
|
|
|
Center[0] := MainForm.center[0];
|
|
|
|
Center[1] := MainForm.center[1];
|
2022-06-23 06:22:32 -04:00
|
|
|
}
|
|
|
|
t := LoadXMLFlameText(RenderFlameFile, FlameNames[iCurrFlame]); // AV
|
|
|
|
if t = '' then continue; // AV: user may delete an item from opened file
|
|
|
|
MainForm.ParseXML(cp, t, true); // the same was done via ListView - but slower
|
|
|
|
|
|
|
|
FileName := renderPath + cp.name + ext;
|
2022-03-08 12:25:51 -05:00
|
|
|
Output.Lines.Add('--- ' + Format(TextByKey('render-status-log-title'), [ExtractFileName(FileName)]) + ' ---');
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-size'), [ImageWidth, ImageHeight]));
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-quality'), [sample_density]));
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-oversampling'), [oversample, filter_radius]));
|
2022-06-23 06:22:32 -04:00
|
|
|
|
|
|
|
{$ifdef CPUX86}
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32-bit float']));
|
|
|
|
{$else}
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['64-bit float']));
|
|
|
|
{$endif}
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
if (ilm) then
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-memorylimit'), [MaxMemory]))
|
|
|
|
else
|
2022-06-23 06:22:32 -04:00
|
|
|
if (UpperCase(ext) = '.PNG') and
|
2022-03-08 12:25:51 -05:00
|
|
|
(ImageWidth * ImageHeight >= 20000000) then
|
|
|
|
begin
|
|
|
|
Output.Lines.Add(TextByKey('render-status-log-largepng-message1'));
|
|
|
|
Output.Lines.Add(TextByKey('render-status-log-largepng-message2'));
|
|
|
|
Output.Lines.Add(TextByKey('render-status-log-largepng-message3'));
|
|
|
|
end;
|
|
|
|
|
|
|
|
if not Assigned(Renderer) then
|
|
|
|
begin
|
|
|
|
// disable screensaver
|
|
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, nil, 0);
|
|
|
|
|
|
|
|
cp.sample_density := Sample_density;
|
|
|
|
cp.spatial_oversample := Oversample;
|
|
|
|
cp.spatial_filter_radius := Filter_Radius;
|
|
|
|
cp.AdjustScale(ImageWidth, ImageHeight);
|
2022-06-23 06:22:32 -04:00
|
|
|
cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ext) = '.PNG');
|
|
|
|
// renderPath := ExtractFilePath(Filename);
|
|
|
|
if chkSave.checked then begin // AV: added check for duplicates
|
|
|
|
t := ExtractFileName(FileName);
|
|
|
|
if XMLEntryExists(t, renderPath + rendersAV) then
|
|
|
|
t := t + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
|
|
|
|
MainForm.SaveXMLFlame(cp, t, renderPath + rendersAV);
|
|
|
|
end;
|
2022-03-08 12:25:51 -05:00
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
oldProg := 0;
|
|
|
|
oldElapsed := 0;
|
|
|
|
edt := 0;
|
|
|
|
ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) *
|
|
|
|
int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) );
|
2022-03-08 12:25:51 -05:00
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal; // AV
|
2022-03-08 12:25:51 -05:00
|
|
|
try
|
|
|
|
|
|
|
|
if not bRenderAll then exit;
|
2022-06-23 06:22:32 -04:00
|
|
|
if iCurrFlame = High(FlameNames){MainForm.ListView1.Items.Count-1} then
|
|
|
|
bRenderAll := false;
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
Renderer := TRenderThread.Create;
|
|
|
|
assert(Renderer <> nil);
|
|
|
|
{
|
|
|
|
if chkThreadPriority.Checked then
|
|
|
|
Renderer.SetPriority(tpLower)
|
|
|
|
else
|
|
|
|
Renderer.SetPriority(tpNormal);
|
|
|
|
}
|
2022-06-23 06:22:32 -04:00
|
|
|
//Renderer.ExportBuffer := chkBinary.Checked;
|
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
if (ilm) then
|
|
|
|
Renderer.MaxMem := lim; //StrToInt(cbMaxMemory.text);
|
|
|
|
Renderer.OnProgress := OnProgress;
|
|
|
|
Renderer.TargetHandle := self.Handle;
|
|
|
|
Renderer.SetCP(cp);
|
|
|
|
|
|
|
|
if chkEmbedFlame.checked then
|
2022-06-23 06:22:32 -04:00
|
|
|
Renderer.EmbedText(Trim(FlameToXML(cp))); // AV
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
Renderer.Priority := tpLower; // tpNormal;
|
|
|
|
Renderer.NrThreads := NrTreads;
|
|
|
|
Renderer.Output := Output.Lines;
|
|
|
|
Renderer.Resume;
|
|
|
|
|
|
|
|
if bRenderAll then Renderer.WaitFor;
|
|
|
|
while Renderer <> nil do Application.ProcessMessages; // wait for HandleThreadCompletion
|
|
|
|
|
|
|
|
except
|
|
|
|
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-rendererror-log'));
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
2022-06-23 06:22:32 -04:00
|
|
|
|
|
|
|
if not Assigned(Renderer) then SetLength(FlameNames, 0); // AV: free memory
|
|
|
|
end // end RenderAll
|
|
|
|
else begin
|
2022-03-08 12:25:51 -05:00
|
|
|
Output.Lines.Add('--- ' + Format(TextByKey('render-status-log-title'), [ExtractFileName(FileName)]) + '" ---');
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-size'), [ImageWidth, ImageHeight]));
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-quality'), [sample_density]));
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-oversampling'), [oversample, filter_radius]));
|
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
{$ifdef CPUX86}
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32-bit float']));
|
|
|
|
{$else}
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['64-bit float']));
|
|
|
|
{$endif}
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
if (ilm) then
|
|
|
|
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-memorylimit'), [lim]))
|
|
|
|
else
|
|
|
|
if (UpperCase(ExtractFileExt(FileName)) = '.PNG') and
|
|
|
|
(ImageWidth * ImageHeight >= 20000000) then
|
|
|
|
begin
|
|
|
|
Output.Lines.Add(TextByKey('render-status-log-largepng-message1'));
|
|
|
|
Output.Lines.Add(TextByKey('render-status-log-largepng-message2'));
|
|
|
|
Output.Lines.Add(TextByKey('render-status-log-largepng-message3'));
|
|
|
|
end;
|
|
|
|
|
|
|
|
if Assigned(Renderer) then begin
|
|
|
|
Output.Lines.Add(TimeToStr(Now) + TextByKey('render-status-shuttingdownrender'));
|
|
|
|
Renderer.Terminate;
|
|
|
|
Renderer.WaitFor;
|
|
|
|
Renderer.Free;
|
|
|
|
Renderer := nil;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if not Assigned(Renderer) then
|
|
|
|
begin
|
|
|
|
// disable screensaver
|
|
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, nil, 0);
|
|
|
|
|
|
|
|
cp.sample_density := Sample_density;
|
|
|
|
cp.spatial_oversample := Oversample;
|
|
|
|
cp.spatial_filter_radius := Filter_Radius;
|
|
|
|
cp.AdjustScale(ImageWidth, ImageHeight);
|
|
|
|
cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ExtractFileExt(FileName)) = '.PNG');
|
|
|
|
renderPath := ExtractFilePath(Filename);
|
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
if chkSave.checked then begin // AV: added check for duplicates
|
|
|
|
t := ExtractFileName(FileName);
|
|
|
|
if XMLEntryExists(t, renderPath + rendersAV) then
|
|
|
|
t := t + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
|
|
|
|
MainForm.SaveXMLFlame(cp, t, renderPath + rendersAV);
|
|
|
|
end;
|
|
|
|
|
|
|
|
oldProg := 0;
|
|
|
|
oldElapsed := 0;
|
|
|
|
edt := 0;
|
|
|
|
ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) *
|
|
|
|
int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) );
|
2022-03-08 12:25:51 -05:00
|
|
|
|
|
|
|
try
|
|
|
|
|
|
|
|
Renderer := TRenderThread.Create;
|
|
|
|
assert(Renderer <> nil);
|
|
|
|
|
|
|
|
if (ilm) then
|
|
|
|
Renderer.MaxMem := lim; //StrToInt(cbMaxMemory.text);
|
2022-06-23 06:22:32 -04:00
|
|
|
//Renderer.ExportBuffer := chkBinary.Checked;
|
2022-03-08 12:25:51 -05:00
|
|
|
Renderer.OnProgress := OnProgress;
|
|
|
|
Renderer.TargetHandle := self.Handle;
|
|
|
|
Renderer.SetCP(cp);
|
|
|
|
if chkEmbedFlame.checked then
|
2022-06-23 06:22:32 -04:00
|
|
|
Renderer.EmbedText(Trim(FlameToXML(cp))); // AV
|
2022-03-08 12:25:51 -05:00
|
|
|
{
|
|
|
|
if chkThreadPriority.Checked then
|
|
|
|
Renderer.SetPriority(tpLower)
|
|
|
|
else
|
|
|
|
Renderer.SetPriority(tpNormal);
|
|
|
|
}
|
|
|
|
Renderer.Priority := tpLower;
|
|
|
|
Renderer.NrThreads := NrTreads;
|
|
|
|
|
|
|
|
Renderer.Output := Output.Lines;
|
|
|
|
Renderer.Resume;
|
|
|
|
|
|
|
|
except
|
|
|
|
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-rendererror-log'));
|
2022-06-23 06:22:32 -04:00
|
|
|
Application.MessageBox(PChar(TextByKey('render-status-rendererror-message')), ApophysisSVN, 48);
|
2022-03-08 12:25:51 -05:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
// enable screensaver
|
|
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, nil, 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.FormShow(Sender: TObject);
|
|
|
|
var
|
|
|
|
Registry: TRegistry;
|
|
|
|
begin
|
|
|
|
{ Read position from registry }
|
|
|
|
Registry := TRegistry.Create;
|
|
|
|
try
|
|
|
|
Registry.RootKey := HKEY_CURRENT_USER;
|
|
|
|
if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Render', False) then
|
|
|
|
begin
|
|
|
|
if Registry.ValueExists('Left') then
|
|
|
|
self.Left := Registry.ReadInteger('Left');
|
|
|
|
if Registry.ValueExists('Top') then
|
|
|
|
self.Top := Registry.ReadInteger('Top');
|
|
|
|
end;
|
|
|
|
Registry.CloseKey;
|
|
|
|
finally
|
|
|
|
Registry.Free;
|
|
|
|
end;
|
|
|
|
|
|
|
|
SaveDialog.FileName := Filename;
|
|
|
|
case renderFileFormat of
|
|
|
|
1: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.bmp');
|
|
|
|
2: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.png');
|
|
|
|
3: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.jpg');
|
|
|
|
end;
|
|
|
|
chkEmbedFlame.Enabled := (renderFileFormat = 2); // AV
|
|
|
|
chkEmbedFlame.Checked := (chkEmbedFlame.Enabled and EmbedFlame); // AV
|
|
|
|
chkSave.Checked := SaveInFlame; // AV
|
|
|
|
if (renderOversample < 1) or (renderOversample > 4) then
|
|
|
|
renderOversample := 2; // AV: prevent checks in future
|
|
|
|
txtOversample.Text := IntToStr(renderOversample);
|
|
|
|
Filter_Radius := max(renderFilterRadius, 0.1); // AV: fixed!
|
|
|
|
txtFilterRadius.Text := FloatToStr(RoundTo(Filter_Radius, -3)); // AV
|
2022-06-23 06:22:32 -04:00
|
|
|
// AV: fixed 'Floating point division by zero' bug
|
2022-03-08 12:25:51 -05:00
|
|
|
sample_density := max(renderDensity, 10);
|
|
|
|
txtDensity.Text := FloatToStr(sample_density);
|
2022-06-23 06:22:32 -04:00
|
|
|
|
|
|
|
// AV: fixed '"" is not a valid integer' bug
|
|
|
|
if bRenderAll then begin
|
|
|
|
ImageWidth := max(renderWidth, 100); // AV
|
|
|
|
ImageHeight := max(renderHeight, 100); // AV
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
ImageWidth := cp.Width; // AV
|
|
|
|
ImageHeight := cp.Height; // AV
|
|
|
|
end;
|
2022-03-08 12:25:51 -05:00
|
|
|
Ratio := ImageWidth / ImageHeight;
|
2022-06-23 06:22:32 -04:00
|
|
|
cbWidth.Text := IntToStr(ImageWidth); // AV
|
|
|
|
cbHeight.Text := IntToStr(ImageHeight); // AV
|
|
|
|
|
|
|
|
ShowMemoryStatus;
|
2022-03-08 12:25:51 -05:00
|
|
|
chkSaveIncompleteRenders.Checked := SaveIncompleteRenders;
|
|
|
|
chkPlaySound.Checked := PlaySoundOnRenderComplete; // AV
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.txtWidthChange(Sender: TObject);
|
|
|
|
begin
|
|
|
|
try
|
|
|
|
ImageWidth := StrToInt(cbWidth.Text);
|
|
|
|
if (cbAspectRatio.ItemIndex > 0) and cbWidth.Focused then
|
|
|
|
begin
|
|
|
|
ImageHeight := Round(ImageWidth / ratio);
|
|
|
|
cbHeight.Text := IntToStr(ImageHeight)
|
|
|
|
end;
|
|
|
|
except
|
|
|
|
end;
|
|
|
|
ShowMemoryStatus;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.txtHeightChange(Sender: TObject);
|
|
|
|
begin
|
|
|
|
try
|
|
|
|
ImageHeight := StrToInt(cbHeight.Text);
|
|
|
|
if (cbAspectRatio.ItemIndex > 0) and cbHeight.Focused then
|
|
|
|
begin
|
|
|
|
ImageWidth := Round(ImageHeight * ratio);
|
|
|
|
cbWidth.Text := IntToStr(ImageWidth)
|
|
|
|
end;
|
|
|
|
except
|
|
|
|
end;
|
|
|
|
ShowMemoryStatus;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.txtOversampleChange(Sender: TObject);
|
|
|
|
var
|
|
|
|
o: integer;
|
|
|
|
begin
|
|
|
|
try
|
|
|
|
o := StrToInt(txtOversample.Text);
|
|
|
|
except
|
|
|
|
txtOversample.Text := IntToStr(Oversample);
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
{
|
|
|
|
// AV: this text field is read-only, moved all checks to FormShow
|
|
|
|
if o > udOversample.Max then
|
|
|
|
begin
|
|
|
|
o := udOversample.Max;
|
|
|
|
txtOversample.Text := IntToStr(o);
|
|
|
|
end
|
|
|
|
else if o < udOversample.Min then
|
|
|
|
begin
|
|
|
|
o := udOversample.Min;
|
|
|
|
txtOversample.Text := IntToStr(o);
|
|
|
|
end;
|
|
|
|
}
|
|
|
|
Oversample := o;
|
|
|
|
ShowMemoryStatus;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.txtFilenameChange(Sender: TObject);
|
|
|
|
var
|
|
|
|
ext : string;
|
|
|
|
begin
|
|
|
|
filename := txtFilename.text;
|
|
|
|
ext := LowerCase(ExtractFileExt(filename));
|
|
|
|
chkEmbedFlame.Enabled := (ext = '.png'); // AV
|
|
|
|
chkEmbedFlame.Checked := (chkEmbedFlame.Enabled and EmbedFlame);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.btnCancelClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
if Assigned(Renderer) or bRenderAll then
|
|
|
|
begin
|
|
|
|
if Assigned(Renderer) then
|
|
|
|
if Renderer.Suspended then begin
|
|
|
|
Renderer.Resume;
|
|
|
|
btnPause.caption := TextByKey('common-pause');
|
|
|
|
end;
|
|
|
|
|
|
|
|
if ConfirmStopRender then begin
|
2022-06-23 06:22:32 -04:00
|
|
|
if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')),
|
|
|
|
ApophysisSVN, 36) = ID_NO then exit;
|
2022-03-08 12:25:51 -05:00
|
|
|
end;
|
|
|
|
|
|
|
|
bRenderAll := false;
|
|
|
|
if Assigned(Renderer) then
|
|
|
|
begin
|
|
|
|
if SaveIncompleteRenders and (not IsLimitingMemory) then
|
|
|
|
Renderer.BreakRender
|
|
|
|
else
|
|
|
|
Renderer.Terminate;
|
|
|
|
Renderer.WaitFor; // ?
|
|
|
|
end;
|
|
|
|
|
|
|
|
ProgressTaskBar.ProgressValue := 0; // AV
|
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
|
2022-06-23 06:22:32 -04:00
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
end else
|
|
|
|
Close;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.txtDensityChange(Sender: TObject);
|
|
|
|
begin
|
|
|
|
Sample_Density := StrToFloatDef(txtDensity.Text, renderDensity); // AV
|
|
|
|
if Sample_Density > 0 then ShowMemoryStatus;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.txtDensityExit(Sender: TObject); // AV
|
|
|
|
begin
|
|
|
|
Sample_Density := StrToFloatDef(txtDensity.Text, renderDensity);
|
|
|
|
txtDensity.Text := FloatToStr(Sample_Density);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.txtFilterRadiusExit(Sender: TObject);
|
|
|
|
begin
|
|
|
|
// AV: we don't need try - except here
|
|
|
|
Filter_Radius := StrToFloatDef(txtFilterRadius.Text, renderFilterRadius);
|
|
|
|
txtFilterRadius.Text := FloatToStr(Filter_Radius); // AV
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.FormActivate(Sender: TObject);
|
|
|
|
begin
|
|
|
|
chkPlaySound.Checked := PlaySoundOnRenderComplete; // AV
|
|
|
|
ShowMemoryStatus; //lblCPUCores.Refresh;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.FormClose(Sender: TObject; var Action: TCloseAction);
|
|
|
|
var
|
|
|
|
Ext: string;
|
|
|
|
Registry: TRegistry;
|
|
|
|
begin
|
|
|
|
Ext := ExtractFileExt(txtFileName.Text);
|
|
|
|
if Ext = '.bmp' then renderFileFormat := 1;
|
|
|
|
if Ext = '.png' then renderFileFormat := 2;
|
|
|
|
if (Ext = '.jpg') or (Ext = '.jpeg') then renderFileFormat := 3;
|
|
|
|
renderFilterRadius := Filter_Radius;
|
|
|
|
renderWidth := ImageWidth;
|
|
|
|
renderHeight := ImageHeight;
|
|
|
|
renderDensity := Sample_density;
|
|
|
|
renderOversample := Oversample;
|
2022-06-23 06:22:32 -04:00
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
EmbedFlame := chkEmbedFlame.Checked; // AV
|
|
|
|
SaveInFlame := chkSave.Checked; // AV
|
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
|
|
|
|
if not Assigned(Renderer) then SetLength(FlameNames, 0); // AV: free memory
|
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
{ Write position to registry }
|
|
|
|
Registry := TRegistry.Create;
|
|
|
|
try
|
|
|
|
Registry.RootKey := HKEY_CURRENT_USER;
|
|
|
|
if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Render', True) then
|
|
|
|
begin
|
|
|
|
Registry.WriteInteger('Top', Top);
|
|
|
|
Registry.WriteInteger('Left', Left);
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
Registry.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.btnPauseClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
if Assigned(Renderer) then
|
|
|
|
if Renderer.Suspended = false then begin
|
2022-06-23 06:22:32 -04:00
|
|
|
Renderer.Suspend;
|
2022-03-08 12:25:51 -05:00
|
|
|
btnPause.caption := TextByKey('common-resume');
|
|
|
|
btnSnapshot.Visible := true; // AV
|
|
|
|
// AV: displaying progress in yellow
|
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.Paused;
|
|
|
|
end else begin
|
2022-06-23 06:22:32 -04:00
|
|
|
Renderer.Resume;
|
2022-03-08 12:25:51 -05:00
|
|
|
btnPause.caption := TextByKey('common-pause');
|
|
|
|
btnSnapshot.Visible := false; // AV
|
2022-06-23 06:22:32 -04:00
|
|
|
// AV: restore the taskbar progress
|
2022-03-08 12:25:51 -05:00
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.FormCloseQuery(Sender: TObject;
|
|
|
|
var CanClose: Boolean);
|
|
|
|
begin
|
|
|
|
if Assigned(Renderer) then
|
2022-06-23 06:22:32 -04:00
|
|
|
if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')),
|
|
|
|
ApophysisSVN, 36) = ID_NO then CanClose := False
|
2022-03-08 12:25:51 -05:00
|
|
|
else
|
|
|
|
begin
|
|
|
|
if Assigned(Renderer) then
|
|
|
|
begin
|
|
|
|
// AV: prevent Apo perpetual hanging when render is paused
|
|
|
|
if Renderer.Suspended then Renderer.Resume; // AV
|
|
|
|
Renderer.Terminate;
|
|
|
|
Renderer.WaitFor;
|
|
|
|
Renderer.Free; // AV
|
|
|
|
Renderer := nil; // AV
|
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.btnSavePresetClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
IFile: TextFile;
|
|
|
|
Title, Filename: string;
|
|
|
|
begin
|
|
|
|
SavePresetForm.txtPresetName.Text := cmbPreset.Text;
|
|
|
|
if SavePresetForm.ShowModal = mrOK then
|
|
|
|
begin
|
|
|
|
Title := Trim(SavePresetForm.txtPresetName.Text);
|
|
|
|
Filename := AppPath + 'Render presets.av';
|
|
|
|
try
|
|
|
|
AssignFile(IFile, FileName);
|
|
|
|
if FileExists(FileName) then
|
|
|
|
begin
|
|
|
|
if EntryExists(Title, FileName) then DeleteEntry(Title, FileName);
|
|
|
|
Append(IFile);
|
|
|
|
end
|
|
|
|
else
|
|
|
|
ReWrite(IFile);
|
|
|
|
WriteLn(IFile, Title + ' {');
|
|
|
|
WriteLn(IFile, Trim(cbWidth.text));
|
|
|
|
WriteLn(IFile, Trim(cbHeight.text));
|
|
|
|
WriteLn(IFile, Trim(txtDensity.text));
|
|
|
|
WriteLn(IFile, Trim(txtFilterRadius.text));
|
|
|
|
WriteLn(IFile, Trim(txtOversample.text));
|
|
|
|
WriteLn(IFile, ExtractFileExt(txtFileName.Text));
|
|
|
|
if (not IsLimitingMemory) then
|
|
|
|
WriteLn(IFile, 'true')
|
|
|
|
else
|
|
|
|
WriteLn(IFile, 'false');
|
|
|
|
WriteLn(IFile, IntToStr(cbMaxMemory.ItemIndex));
|
|
|
|
WriteLn(IFile, '}');
|
|
|
|
WriteLn(IFile, '');
|
|
|
|
CloseFile(IFile);
|
|
|
|
except on EInOutError do
|
|
|
|
begin
|
|
|
|
Application.MessageBox(PChar(TextByKey('render-prestatus-saveerror-preset')),
|
2022-06-23 06:22:32 -04:00
|
|
|
ApophysisSVN, 16);
|
2022-03-08 12:25:51 -05:00
|
|
|
Exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
ListPresets;
|
|
|
|
cmbPreset.ItemIndex := cmbPreset.Items.count - 1;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.btnSnapshotClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
tryAgain: boolean;
|
|
|
|
begin
|
|
|
|
if Assigned(Renderer) then
|
|
|
|
if Renderer.Suspended = true then
|
|
|
|
begin
|
|
|
|
repeat
|
|
|
|
tryAgain := false;
|
|
|
|
try
|
|
|
|
Renderer.DoSnapshot; // AV: to save mid-render images
|
|
|
|
Renderer.SaveImage(FileName);
|
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
// AV: show saved image if needed
|
|
|
|
if ShowRenderImage or (Sender = ProgressTaskbar.TaskBarButtons[0]) then
|
2022-03-08 12:25:51 -05:00
|
|
|
if FileExists(FileName) then
|
|
|
|
ShellExecute(Application.handle, PChar('open'),
|
|
|
|
PChar(ExtractFileName(FileName)), nil, PChar(renderPath),
|
|
|
|
SW_SHOWNORMAL);
|
|
|
|
except
|
|
|
|
on e: Exception do begin
|
|
|
|
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-saveerror-log'));
|
|
|
|
tryAgain := (Application.MessageBox(PChar(TextByKey('render-status-saveerror-message1') + #13#10 + e.Message +
|
|
|
|
#13#10 + TextByKey('render-status-saveerror-message1')), 'Error', MB_RETRYCANCEL or MB_ICONERROR) = IDRETRY);
|
|
|
|
// AV: displaying status in red
|
|
|
|
ProgressTaskBar.ProgressState := TTaskBarProgressState.Error;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
until tryAgain = false;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.btnBrowseClick(Sender: TObject);
|
|
|
|
var
|
2022-06-23 06:22:32 -04:00
|
|
|
fn, ext: string;
|
2022-03-08 12:25:51 -05:00
|
|
|
begin
|
|
|
|
SaveDialog.Filename := Filename;
|
|
|
|
case renderFileFormat of
|
|
|
|
1: SaveDialog.DefaultExt := 'bmp';
|
|
|
|
2: SaveDialog.DefaultExt := 'png';
|
|
|
|
3: SaveDialog.DefaultExt := 'jpg';
|
|
|
|
end;
|
2022-06-23 06:22:32 -04:00
|
|
|
SaveDialog.FilterIndex := renderFileFormat;
|
|
|
|
if SaveDialog.Execute then
|
2022-03-08 12:25:51 -05:00
|
|
|
begin
|
2022-06-23 06:22:32 -04:00
|
|
|
fn := SaveDialog.FileName;
|
2022-03-08 12:25:51 -05:00
|
|
|
ext := LowerCase(ExtractFileExt(fn));
|
2022-06-23 06:22:32 -04:00
|
|
|
if (ext = '.jpg') or (ext = '.jpeg')then
|
|
|
|
renderFileFormat := 3
|
|
|
|
else if (ext = '.png') then
|
|
|
|
renderFileFormat := 2
|
|
|
|
else // if (ext = '.bmp') or (ext = '.dib') then
|
|
|
|
renderFileFormat := 1;
|
2022-03-08 12:25:51 -05:00
|
|
|
txtFileName.Text := ChangeFileExt(fn, ext);
|
2022-06-23 06:22:32 -04:00
|
|
|
renderPath := ExtractFilePath(fn);
|
2022-03-08 12:25:51 -05:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.ListPresets;
|
|
|
|
{ List identifiers in file }
|
|
|
|
var
|
|
|
|
i, p: integer;
|
|
|
|
Title: string;
|
|
|
|
FStrings: TStringList;
|
|
|
|
begin
|
|
|
|
FStrings := TStringList.Create;
|
|
|
|
try
|
|
|
|
if fileExists(AppPath + 'Render presets.av') then begin
|
|
|
|
FStrings.LoadFromFile(AppPath + 'Render presets.av');
|
|
|
|
cmbPreset.Clear;
|
|
|
|
if (Pos('{', FStrings.Text) <> 0) then begin
|
|
|
|
for i := 0 to FStrings.Count - 1 do begin
|
|
|
|
p := Pos('{', FStrings[i]);
|
|
|
|
if (p <> 0) then begin
|
|
|
|
Title := Trim(Copy(FStrings[i], 1, p - 1));
|
|
|
|
if Title <> '' then begin
|
|
|
|
cmbPreset.Items.add(Copy(FStrings[i], 1, p - 1));
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
FStrings.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.btnDeletePresetClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
Title, Filename: string;
|
|
|
|
begin
|
|
|
|
Title := Trim(cmbPreset.Text);
|
|
|
|
if Title = '' then exit;
|
|
|
|
Filename := AppPath + 'Render presets.av';
|
|
|
|
if EntryExists(Title, FileName) then DeleteEntry(Title, FileName);
|
|
|
|
ListPresets;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.cmbPresetChange(Sender: TObject);
|
|
|
|
var
|
2022-06-23 06:22:32 -04:00
|
|
|
chk: shortint; // AV
|
2022-03-08 12:25:51 -05:00
|
|
|
i, j: integer;
|
|
|
|
FStrings: TStringList;
|
|
|
|
Title, Filename: string;
|
|
|
|
begin
|
|
|
|
Title := Trim(cmbPreset.Text);
|
|
|
|
Filename := AppPath + 'Render presets.av'; // AV: added file extension
|
|
|
|
if Title = '' then exit;
|
|
|
|
if EntryExists(Title, FileName) then
|
|
|
|
begin
|
|
|
|
// Load preset
|
|
|
|
FStrings := TStringList.Create;
|
|
|
|
try
|
|
|
|
FStrings.LoadFromFile(Filename);
|
|
|
|
for i := 0 to FStrings.Count - 1 do
|
|
|
|
if Pos(LowerCase(Title) + ' {', Lowercase(FStrings[i])) <> 0 then
|
|
|
|
begin
|
|
|
|
chk := cbAspectRatio.ItemIndex; // AV
|
|
|
|
cbAspectRatio.ItemIndex := 0;
|
|
|
|
j := i + 1;
|
|
|
|
cbWidth.Text := FStrings[j];
|
|
|
|
inc(j);
|
|
|
|
cbHeight.text := FStrings[j];
|
|
|
|
cbAspectRatio.ItemIndex := chk;
|
|
|
|
inc(j);
|
|
|
|
txtDensity.text := FStrings[j];
|
|
|
|
inc(j);
|
|
|
|
txtFilterRadius.text := FStrings[j];
|
|
|
|
inc(j);
|
|
|
|
txtOversample.text := FStrings[j];
|
|
|
|
inc(j);
|
|
|
|
txtFileName.Text := ChangeFileExt(txtFileName.Text, FStrings[j]);
|
2022-06-23 06:22:32 -04:00
|
|
|
inc(j, 2);
|
|
|
|
// AV: avoiding conflicts with 32- and 64-bit versions
|
|
|
|
cbMaxMemory.ItemIndex := min(StrToInt(FStrings[j]), cbMaxMemory.Items.Count-1);
|
2022-03-08 12:25:51 -05:00
|
|
|
break;
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
FStrings.Free;
|
|
|
|
end
|
|
|
|
end;
|
|
|
|
ImageWidth := StrToInt(cbWidth.Text);
|
|
|
|
ImageHeight := StrToInt(cbHeight.Text);
|
|
|
|
Sample_Density := StrToFloat(txtDensity.Text);
|
|
|
|
ShowMemoryStatus;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.DoPostProcess;
|
|
|
|
begin
|
|
|
|
frmPostProcess.cp := cp;
|
|
|
|
frmPostProcess.SetRenderer(Renderer.GetRenderer);
|
|
|
|
frmPostProcess.SetControlPoint(CP);
|
|
|
|
frmPostProcess.SetImageName(FileName);
|
|
|
|
frmPostProcess.Show;
|
|
|
|
end;
|
|
|
|
|
2022-06-23 06:22:32 -04:00
|
|
|
function GetWinVersion: TWin32Version;
|
|
|
|
{ Returns current version of a host Win32 platform }
|
|
|
|
var
|
|
|
|
wMinor, wMajor: integer;
|
|
|
|
begin
|
|
|
|
Result := wvUnknown;
|
|
|
|
wMinor := Win32MinorVersion; // AV
|
|
|
|
wMajor := Win32MajorVersion; // AV
|
|
|
|
if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
|
|
|
|
if (wMajor > 4) or ((wMajor = 4) and (wMinor > 0)) then
|
|
|
|
Result := wvWin98
|
|
|
|
else
|
|
|
|
Result := wvWin95
|
|
|
|
else
|
|
|
|
if wMajor <= 4 then
|
|
|
|
Result := wvWinNT
|
|
|
|
else if wMajor = 5 then
|
|
|
|
begin // AV
|
|
|
|
if wMinor = 0 then
|
|
|
|
Result := wvWin2000
|
|
|
|
else if wMinor >= 1 then
|
|
|
|
Result := wvWinXP
|
|
|
|
end
|
|
|
|
else if wMajor = 6 then
|
|
|
|
begin // AV
|
|
|
|
if wMinor = 0 then
|
|
|
|
Result := wvWinVista
|
|
|
|
else if wMinor >= 1 then
|
|
|
|
Result := wvWin7
|
|
|
|
end
|
|
|
|
else if wMajor >= 7 then
|
|
|
|
Result := wvWinFutureFromOuterSpace;
|
|
|
|
end;
|
|
|
|
|
2022-03-08 12:25:51 -05:00
|
|
|
function TRenderForm.WindowsExit(RebootParam: Longword = EWX_POWEROFF or EWX_FORCE): Boolean;
|
|
|
|
var
|
|
|
|
TTokenHd: THandle;
|
|
|
|
TTokenPvg: TTokenPrivileges;
|
|
|
|
cbtpPrevious: DWORD;
|
|
|
|
rTTokenPvg: TTokenPrivileges;
|
|
|
|
pcbtpPreviousRequired: DWORD;
|
|
|
|
tpResult: Boolean;
|
2022-06-23 06:22:32 -04:00
|
|
|
WinVersion: TWin32Version; // AV
|
2022-03-08 12:25:51 -05:00
|
|
|
const
|
|
|
|
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
|
|
|
|
begin
|
2022-06-23 06:22:32 -04:00
|
|
|
WinVersion := GetWinVersion; // AV: we don't need to calc it many times
|
|
|
|
if ((WinVersion = wvWinNT) or
|
|
|
|
(WinVersion = wvWin2000) or
|
|
|
|
(WinVersion = wvWinXP) or
|
|
|
|
(WinVersion = wvWinVista) or
|
|
|
|
(WinVersion = wvWin7) or
|
|
|
|
(WinVersion = wvWinFutureFromOuterSpace)) then
|
2022-03-08 12:25:51 -05:00
|
|
|
begin
|
|
|
|
tpResult := OpenProcessToken(GetCurrentProcess(),
|
|
|
|
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
|
|
|
|
TTokenHd);
|
|
|
|
if tpResult then
|
|
|
|
begin
|
|
|
|
tpResult := LookupPrivilegeValue(nil,
|
|
|
|
SE_SHUTDOWN_NAME,
|
|
|
|
TTokenPvg.Privileges[0].Luid);
|
|
|
|
TTokenPvg.PrivilegeCount := 1;
|
|
|
|
TTokenPvg.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
|
|
|
|
cbtpPrevious := SizeOf(rTTokenPvg);
|
|
|
|
pcbtpPreviousRequired := 0;
|
|
|
|
if tpResult then
|
|
|
|
Windows.AdjustTokenPrivileges(TTokenHd,
|
|
|
|
False,
|
|
|
|
TTokenPvg,
|
|
|
|
cbtpPrevious,
|
|
|
|
rTTokenPvg,
|
|
|
|
pcbtpPreviousRequired);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
Result := ExitWindowsEx(RebootParam, 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.chkPlaySoundClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
PlaySoundOnRenderComplete := chkPlaySound.Checked;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.chkSaveIncompleteRendersClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
SaveIncompleteRenders := chkSaveIncompleteRenders.Checked;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.btnGoToClick(Sender: TObject);
|
|
|
|
var
|
2022-06-23 06:22:32 -04:00
|
|
|
path: string;
|
2022-03-08 12:25:51 -05:00
|
|
|
begin
|
|
|
|
path := ExtractFilePath(txtFilename.Text);
|
|
|
|
if (path <> '') then WinShellExecute('open', path);
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure TRenderForm.cbAspectRatioChange(Sender: TObject);
|
|
|
|
begin
|
|
|
|
case cbAspectRatio.ItemIndex of
|
|
|
|
1: Ratio := ImageWidth / ImageHeight; // AV: replaced "Keep aspect ratio"
|
|
|
|
2: Ratio := 1.5;
|
|
|
|
3: Ratio := 4 / 3;
|
|
|
|
4: Ratio := 1.25;
|
|
|
|
5: Ratio := 16 / 9;
|
|
|
|
6: Ratio := 1.6;
|
|
|
|
7: Ratio := 21 / 9;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.cbHeightExit(Sender: TObject); // AV
|
|
|
|
begin
|
|
|
|
ImageHeight := StrToIntDef(cbHeight.Text, renderHeight);
|
|
|
|
cbHeight.Text := IntToStr(ImageHeight);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.cbWidthExit(Sender: TObject); // AV
|
|
|
|
begin
|
|
|
|
ImageWidth := StrToIntDef(cbWidth.Text, renderWidth);
|
|
|
|
cbWidth.Text := IntToStr(ImageWidth);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.cbMaxMemoryChange(Sender: TObject);
|
|
|
|
begin
|
|
|
|
//cbMaxMemory.enabled := IsLimitingMemory;
|
|
|
|
chkPostProcess.Enabled := not IsLimitingMemory;
|
|
|
|
chkSaveIncompleteRenders.Enabled := not IsLimitingMemory;
|
|
|
|
//btnRender.Enabled := (ApproxMemory <= PhysicalMemory) or (cbMaxMemory.ItemIndex > 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.btnDonateClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
WinShellExecute('open', 'https://www.donationalerts.com/r/fract_alice');
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderForm.btnSaveLogClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
fn: string;
|
|
|
|
sl: TStringList;
|
|
|
|
begin
|
2022-06-23 06:22:32 -04:00
|
|
|
if OpenSaveFileDialog(RenderForm, '.log',
|
2022-03-08 12:25:51 -05:00
|
|
|
Format('Render-Log (*.txt;*.log)|*.txt;*.log|%s|*.*', [TextByKey('common-filter-allfiles')]),
|
|
|
|
SaveDialog.InitialDir, TextByKey('common-browse'), fn, false, true, false, false)
|
2022-06-23 06:22:32 -04:00
|
|
|
then begin
|
2022-03-08 12:25:51 -05:00
|
|
|
sl := TStringList.Create;
|
|
|
|
sl.Text := Output.Text;
|
|
|
|
sl.SaveToFile(fn);
|
|
|
|
sl.Destroy;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|
|
|