OpenCL.Seascape/OpenCL.Seascape.mq5

194 lines
6.1 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:14:28 +02:00
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+