Hi,
I'm having problems drawing on a canvas with my raytracer. the basic
idea is as follows:
The Main app form opens a modal form called TraceFrm.
TraceFrm contains a scroll bar and an edit to inform the user of the
trace progress.
When the form is shown, it sets up it's progress bar, opens another
form called OutputFrm (on which I have an Image control), and starts a
separate thread to do the actual raytracing ( called TraceThread).
When OutputFrm is opened it contains an image control (called image1).
It assigns a bitmap of the appropriate size to the graphic property.
During the raytrace, the trace thread uses the synchronize method to
alter the pixels property of the canvas property of the image1
control.
Then when the raytace finishes, OutputFrm.Image1.Picture is either
saved to file or assigned to the clipboard.
There's are just two small snags.....
1. When I'm just writing to a targa file, and not using any of the
above code, everything runs nice and quick. When i try to write to the
canvas of the image control, the program runs like a particularly
tired snail.
2. Nothing ever actually appears in the image control!!!
Any ideas???
Relevant source below
PS. I hope I'm not asking a whole load of FAQ's here......
unit TraceForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
ComCtrls, StdCtrls;
type
TTraceFrm = class(TForm)
{SNIP}
end;
var
TraceFrm: TTraceFrm;
Tracing:boolean;
implementation
uses TraceExceptions, TraceThrd, OutputForm,ClipBrd, TraceMgr;
{$R *.DFM}
var
MyThread:TraceThread;
{SNIP}
procedure TTraceFrm.FormShow(Sender: TObject);
begin
{SNIP}
if ViewTrace then OutputFrm.WindowState:=wsNormal else
OutputFrm.WindowState:=wsMinimized;
if ViewTrace or BitmapOut or ClipboardOut then OutputFrm.Show;
{SNIP}
end;
procedure TTraceFrm.Finished(Sender:TObject);
begin
Tracing:=false;
if BitmapOut then OutputFrm.Image1.Picture.SaveToFile(BitmapOutFile);
if ClipboardOut then Clipboard.Assign(OutputFrm.Image1.Picture);
if ViewTrace or BitmapOut or ClipboardOut then OutputFrm.Close;
Close;
end;
initialization
Tracing:=false;
end.
unit OutputForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
ExtCtrls;
type
TOutputFrm = class(TForm)
ScrollBox1: TScrollBox;
Image1: TImage;
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
OutputFrm: TOutputFrm;
implementation
uses DataMgr;
{$R *.DFM}
procedure TOutputFrm.FormShow(Sender: TObject);
var
Bitmap:TBitmap;
begin
Bitmap:=TBitmap.Create;
Bitmap.Width:=Camera.ResX;
Bitmap.Height:=Camera.ResY;
Image1.Picture.Graphic:=Bitmap;
end;
procedure TOutputFrm.FormClose(Sender: TObject; var Action:
TCloseAction);
begin
{Image1.Picture.Graphic.Free;}
end;
end.
unit TraceThrd;
{Martin Harvey 11/12/96 }
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
ComCtrls, StdCtrls;
type
TraceThread = class(TThread)
constructor Create(PBar:TProgressBar;OpEdit:TEdit);
private
{ Private declarations }
Progbar:TProgressBar;
OperationText:TEdit;
procedure WriteOper1;
procedure WriteOper2;
procedure WriteOperLine;
procedure SetMax;
procedure SetPos;
procedure WriteTargaError;
procedure WriteTexMapError;
procedure WriteBMPData;
protected
procedure Execute; override;
end;
implementation
uses TraceMgr,DataMgr,Targa,VCMath,TraceExceptions,OutputForm;
type
LineData=array[0..2047] of TColour;
var
GlobalXpos,GlobalYpos:integer;
BMPData:TColor;
{ A VERY BIG SNIP}
procedure TraceThread.WriteBMPData;
begin;
OutputFrm.Image1.Canvas.Pixels[GlobalXpos,GlobalYpos]:=BMPData;
end;
procedure TraceThread.Execute;
var
OutputTarga:TTargaFile;
TempLine,LastLine,ThisLine:^LineData;
PlaneUp,PlaneRight,ViewDir,RayDir,UpDir,
RaySweepY,RaySweepX:TVector;
Xpos,Ypos:integer;
LongXpos,LongYPos,LongResX,LongResY:double;
RayColour:TColour;
RayData:TColData;
Xwrite:integer;
begin
{SNIP}
try
try
{SNIP}
OutputFrm.Image1.Canvas.Pen.Style:=psSolid;
{SNIP}
for Ypos:=0 to Camera.ResY do
begin
GlobalYpos:=Ypos;
{SNIP}
for Xpos:=0 to Camera.ResX do
begin
if terminated then raise ETraceAbort.Create('Abort button
pressed');
LongXpos:=Xpos;
GlobalXpos:=Xpos;
LongYpos:=Ypos;
{SNIP}
if Ypos>0 then
begin
{SNIP}
if TargaOut then OutputTarga.WritePix(RayData);
if ViewTrace or BitmapOut or ClipboardOut then
begin
BMPData:=FloatToWin(RayColour);
Synchronize(WriteBMPData);
end;
end;
end;
TempLine:=LastLine;
LastLine:=ThisLine;
ThisLine:=TempLine;
end;
finally
{SNIP}
end;
except
{SNIP}
end;
end;
end.
Martin Harvey
Uni email: mc...@cam.ac.uk
Home email: mc...@harvey27.demon.co.uk
Uni web pages: http://www-stu.pem.cam.ac.uk/~mch24/
Home web pages: shortly to appear on the demon server