194 lines
6.1 KiB
MQL5
194 lines
6.1 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| Seascape.mq5 |
|
||
|
//| Copyright 2016, MetaQuotes Software Corp. |
|
||
|
//| https://www.mql5.com |
|
||
|
//+------------------------------------------------------------------+
|
||
|
#property copyright "Copyright 2016, MetaQuotes Software Corp."
|
||
|
#property link "https://www.mql5.com"
|
||
|
#property version "1.00"
|
||
|
|
||
|
//#resource "seascape.cl" as string ExtCL
|
||
|
|
||
|
uint ExtSizeX=640; // Width
|
||
|
uint ExtSizeY=360; // Height
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Initialize OpenCL engine |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool ModelInitialize(int &cl_ctx,int &cl_prg,int &cl_krn,int &cl_mem)
|
||
|
{
|
||
|
//--- initializing OpenCL objects
|
||
|
if((cl_ctx=CLContextCreate())==INVALID_HANDLE)
|
||
|
{
|
||
|
Print("OpenCL not found");
|
||
|
return(false);
|
||
|
}
|
||
|
//--- compile the program
|
||
|
string build_log;
|
||
|
if((cl_prg=CLProgramCreate(cl_ctx,ExtCL,build_log))==INVALID_HANDLE)
|
||
|
{
|
||
|
//--- free
|
||
|
CLContextFree(cl_ctx);
|
||
|
cl_ctx=INVALID_HANDLE;
|
||
|
//---
|
||
|
Print("OpenCL program create failed: ",build_log);
|
||
|
return(false);
|
||
|
}
|
||
|
//--- kernel
|
||
|
if((cl_krn=CLKernelCreate(cl_prg,"Seascape"))==INVALID_HANDLE)
|
||
|
{
|
||
|
//--- free
|
||
|
CLProgramFree(cl_prg);
|
||
|
cl_prg=INVALID_HANDLE;
|
||
|
|
||
|
CLContextFree(cl_ctx);
|
||
|
cl_ctx=INVALID_HANDLE;
|
||
|
//---
|
||
|
Print("OpenCL kernel create failed");
|
||
|
return(false);
|
||
|
}
|
||
|
//--- create buffer
|
||
|
ExtSizeX=(uint)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
|
||
|
ExtSizeY=(uint)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
|
||
|
|
||
|
if((cl_mem=CLBufferCreate(cl_ctx,ExtSizeX*ExtSizeY*sizeof(uint),CL_MEM_READ_WRITE))==INVALID_HANDLE)
|
||
|
{
|
||
|
//--- free objects
|
||
|
CLKernelFree(cl_krn);
|
||
|
cl_krn=INVALID_HANDLE;
|
||
|
|
||
|
CLProgramFree(cl_prg);
|
||
|
cl_prg=INVALID_HANDLE;
|
||
|
|
||
|
CLContextFree(cl_ctx);
|
||
|
cl_ctx=INVALID_HANDLE;
|
||
|
//---
|
||
|
Print("OpenCL buffer create failed");
|
||
|
return(false);
|
||
|
}
|
||
|
|
||
|
CLSetKernelArgMem(cl_krn,1,cl_mem);
|
||
|
//---
|
||
|
return(true);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Check and resize the window |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool ModelResize(const int cl_ctx,const int cl_krn,int &cl_mem)
|
||
|
{
|
||
|
uint width =(uint)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
|
||
|
uint height=(uint)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
|
||
|
//--- correction
|
||
|
width=(width + 7) & ~7; // align to 8
|
||
|
if(width<8)
|
||
|
width=8;
|
||
|
|
||
|
if(height<8)
|
||
|
height=8;
|
||
|
//--- the same size?
|
||
|
if(ExtSizeX!=width || ExtSizeY!=height)
|
||
|
{
|
||
|
ExtSizeX=width;
|
||
|
ExtSizeY=height;
|
||
|
//--- create buffer
|
||
|
if(cl_mem!=INVALID_HANDLE)
|
||
|
CLBufferFree(cl_mem);
|
||
|
|
||
|
if((cl_mem=CLBufferCreate(cl_ctx,ExtSizeX*ExtSizeY*sizeof(uint),CL_MEM_READ_WRITE))!=INVALID_HANDLE)
|
||
|
{
|
||
|
CLSetKernelArgMem(cl_krn,1,cl_mem);
|
||
|
return(true);
|
||
|
}
|
||
|
}
|
||
|
//--- no changes
|
||
|
return(false);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Shutdown OpenCL engine |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void ModelShutdown(int cl_ctx,int cl_prg,int cl_krn,int cl_mem)
|
||
|
{
|
||
|
//--- remove OpenCL objects
|
||
|
if(cl_mem!=INVALID_HANDLE)
|
||
|
{
|
||
|
CLBufferFree(cl_mem);
|
||
|
cl_mem=INVALID_HANDLE;
|
||
|
}
|
||
|
|
||
|
if(cl_krn!=INVALID_HANDLE)
|
||
|
{
|
||
|
CLKernelFree(cl_krn);
|
||
|
cl_krn=INVALID_HANDLE;
|
||
|
}
|
||
|
|
||
|
if(cl_prg!=INVALID_HANDLE)
|
||
|
{
|
||
|
CLProgramFree(cl_prg);
|
||
|
cl_prg=INVALID_HANDLE;
|
||
|
}
|
||
|
|
||
|
if(cl_ctx!=INVALID_HANDLE)
|
||
|
{
|
||
|
CLContextFree(cl_ctx);
|
||
|
cl_ctx=INVALID_HANDLE;
|
||
|
}
|
||
|
//---
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Script program start function |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void OnStart()
|
||
|
{
|
||
|
int cl_ctx=INVALID_HANDLE,cl_prg=INVALID_HANDLE;
|
||
|
int cl_krn=INVALID_HANDLE,cl_mem=INVALID_HANDLE;
|
||
|
//--- prepare the chart
|
||
|
ChartSetInteger(0,CHART_SHOW,false);
|
||
|
ChartRedraw();
|
||
|
//--- initializing OpenCL objects
|
||
|
if(ModelInitialize(cl_ctx,cl_prg,cl_krn,cl_mem))
|
||
|
{
|
||
|
uint buf[];
|
||
|
uint work[2];
|
||
|
uint offset[2]= {0,0};
|
||
|
string objname="OpenCL_"+IntegerToString(ChartID());
|
||
|
string resname="::Seascape_"+IntegerToString(ChartID());
|
||
|
//--- create object and empty picture
|
||
|
ObjectCreate(0,objname,OBJ_BITMAP_LABEL,0,0,0);
|
||
|
ObjectSetInteger(0,objname,OBJPROP_XDISTANCE,0);
|
||
|
ObjectSetInteger(0,objname,OBJPROP_YDISTANCE,0);
|
||
|
|
||
|
ArrayResize(buf,ExtSizeX*ExtSizeY);
|
||
|
ResourceCreate(resname,buf,ExtSizeX,ExtSizeY,0,0,ExtSizeX,COLOR_FORMAT_XRGB_NOALPHA);
|
||
|
ObjectSetString(0,objname,OBJPROP_BMPFILE,resname);
|
||
|
//--- render
|
||
|
work[0]=ExtSizeX;
|
||
|
work[1]=ExtSizeY;
|
||
|
|
||
|
for(float time=0; !IsStopped(); time+=0.04f)
|
||
|
{
|
||
|
//--- check the resolution
|
||
|
if(ModelResize(cl_ctx,cl_krn,cl_mem))
|
||
|
{
|
||
|
work[0]=ExtSizeX;
|
||
|
work[1]=ExtSizeY;
|
||
|
ArrayResize(buf,ExtSizeX*ExtSizeY);
|
||
|
}
|
||
|
//--- rendering the frame
|
||
|
CLSetKernelArg(cl_krn,0,time);
|
||
|
CLExecute(cl_krn,2,offset,work);
|
||
|
//--- take the frame data, save in memory and draw it
|
||
|
CLBufferRead(cl_mem,buf);
|
||
|
ResourceCreate(resname,buf,ExtSizeX,ExtSizeY,0,0,ExtSizeX,COLOR_FORMAT_XRGB_NOALPHA);
|
||
|
|
||
|
ChartRedraw();
|
||
|
Sleep(0);
|
||
|
}
|
||
|
//--- remove OpenCL objects
|
||
|
ModelShutdown(cl_ctx,cl_prg,cl_krn,cl_mem);
|
||
|
//--- remove object
|
||
|
ObjectDelete(0,objname);
|
||
|
}
|
||
|
//---
|
||
|
ChartSetInteger(0,CHART_SHOW,true);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|