// FreeFrame Open Video Plugin GL Example // www.freeframe.org // johnday@camart.co.uk { Copyright (c) 2007 John Day All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of FreeFrame nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } unit plugin; interface uses sysutils,syncobjs,classes, gl,glu, ffstructs,math, {$IFDEF LINUX} Types;{$ENDIF} {$IFDEF WIN32} windows;{$ENDIF} const NumberOfParameters=5; type pdw = ^Dword; pw = ^word; pb = ^byte; type TBlockPoint=record x,y:integer; end; TBlock=record p1,p2,p3,p4:TBlockPoint; fadestate:integer; fadetargettime:single; fadevalue,fadespeed:single; end; TFreeFramePlugin = class(TObject) private // standard FreeFrame VideoInfoStruct: TVideoInfoStruct; // openGL FreeFrame ViewPortStruct:TPLuginGLViewportStruct; ProcessOpenGLStruct:TProcessOpenGLStruct; // Plugin Parameters ParameterArray: array [0..NumberOfParameters-1] of single; ParameterDisplayValue: array [0..NumberOfParameters-1,0..15] of char; // this plugins local vars Perspective:single; blocks:array of TBlock; totalblocks:integer; alphaorder:array of integer; prevtime:double; absoluteTime:double; hardwidth,hardheight:integer; procedure NewBlock(id:integer); protected public constructor Create; destructor Destroy; // functions that are instance specific function InitialiseInstance(pParam: pointer): pointer; function DeInitialiseInstance: pointer; function InitialiseGLInstance(pParam: pointer):pointer; function DeInitialiseGLInstance: pointer; function GetParameterDisplay(pParam: pointer): pointer; function SetParameter(pParam: pointer): pointer; function GetParameter(pParam: pointer): pointer; function ProcessFrame(pParam: pointer): pointer; function ProcessOpenGl(pParam:pointer):pointer; function SetTime(pParam:pointer):pointer; end; // Global functions that are not instance specific ... function InitilisePlugin:pointer; function DeInitilisePlugin:pointer; function GetInfo:pointer; function GetExtendedInfo:pointer; function GetNumParameters(pParam: pointer): pointer; function GetParameterName(pParam: pointer): pointer; function GetParameterType(pParam: pointer): pointer; function GetParameterDefault(pParam: pointer): pointer; function GetPluginCaps(pParam: pointer): pointer; var PluginInfoStruct: TPluginInfoStruct; PluginExtendedInfoStruct: TPluginExtendedInfoStruct; ParameterNames: array [0..NumberOfParameters-1,0..15] of char; ParameterDefaults: array [0..NumberOfParameters-1] of single; ParameterTypes: array [0..NumberOfParameters-1] of dword; implementation //------------------------------------------------------------------------------ // // GLOBAL FUNCTIONS // //------------------------------------------------------------------------------ function InitilisePlugin:pointer; begin ParameterNames[0]:='Block Count '; // MUST be 15 chars ParameterNames[1]:='Fade Time '; // MUST be 15 chars ParameterNames[2]:='Fade TimeRandom'; // MUST be 15 chars ParameterNames[3]:='Block Max Size '; // MUST be 15 chars ParameterNames[4]:='Block Min Size '; // MUST be 15 chars ParameterTypes[0]:=10; ParameterTypes[1]:=10; ParameterTypes[2]:=10; ParameterTypes[3]:=10; ParameterTypes[4]:=10; ParameterDefaults[0]:=0.05; ParameterDefaults[1]:=0.05; ParameterDefaults[2]:=0.5; ParameterDefaults[3]:=0.5; ParameterDefaults[4]:=0.3; result:=pointer(0); end; function DeInitilisePlugin:pointer; begin result:=pointer(0); end; //------------------------------------------------------------------------------ function GetInfo:pointer; begin with PluginInfoStruct do begin APIMajorVersion:=1; APIMinorVersion:=0; PluginUniqueID:='GLX1'; PluginName:='JD-FilterBoards'; PluginType:=0; // 0 = effect - 1 = source end; result:=@PluginInfoStruct; end; //------------------------------------------------------------------------------ function GetExtendedInfo:pointer; begin with PluginExtendedInfoStruct do begin PluginMajorVersion:=1; PluginMinorVersion:=0; pDescription:= nil; pAbout:= nil; FreeFrameExtendedDataSize:= 0; FreeFrameExtendedDataBlock:= nil; end; result:=@pluginExtendedInfoStruct; end; //------------------------------------------------------------------------------ function GetPluginCaps(pParam: pointer): pointer; begin case integer(pParam) of 0: result:=pointer(0); // 0=16bit - not yet supported in this sample plugin 1: result:=pointer(0); // 1=24bit - supported 2: result:=pointer(0); // 2=32bit 3: result:=pointer(0); // this plugin dosen't support copy yet 4: result:=pointer(1); // is an opengl plugin 5: result:=pointer(1); // this plugin supports setTime 10: result:=pointer(1); // minimum number of inputs 11: result:=pointer(1); // maximum number of inputs 15: result:=pointer(0); // optimization // 0 (FF_CAP_PREFER_NONE) = no preference (GL plugins must return 0) // 1 (FF_CAP_PREFER_INPLACE) = InPlace processing is faster // 2 (FF_CAP_PREFER_COPY) = Copy processing is faster // 3 (FF_CAP_PREFER_BOTH) = Both are optimized else result:=pointer($FFFFFFFF) // unknown PluginCapsIndex end; end; //------------------------------------------------------------------------------ function GetNumParameters(pParam: pointer): pointer; begin result:=pointer(NumberOfParameters); end; //------------------------------------------------------------------------------ function GetParameterName(pParam: pointer): pointer; begin if integer(pParam)blocks[i].fadetargettime then begin blocks[i].fadetargettime:=now+(ParameterArray[1]*5000)+(random(round(ParameterArray[2]*5))*1000); blocks[i].fadespeed:=100/(blocks[i].fadetargettime-now); inc(blocks[i].fadestate); if blocks[i].fadestate=3 then begin blocks[i].fadestate:=0; blocks[i].fadevalue:=0; NewBlock(i); end; end; case blocks[i].fadestate of 0: blocks[i].fadevalue:=blocks[i].fadevalue+blocks[i].fadespeed; 1: blocks[i].fadevalue:=1.0; 2: blocks[i].fadevalue:=blocks[i].fadevalue-blocks[i].fadespeed; end; end; // dont play with viewport (unless you stay within current and reset afterwards) //glViewport(ViewportStruct.x,ViewportStruct.y,ViewportStruct.Width,ViewportStruct.Height); // gl should have been set to default state by host before this point // setup required projection (host will not know what you want so set it up yourself) glMatrixMode(GL_PROJECTION); glLoadIdentity; glOrtho(0,ViewportStruct.Width,0,ViewportStruct.Height,1,-1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,InputTexture.Handle); // sort into alpha order (crappy bubble sort) for i:=0 to totalblocks-1 do alphaorder[i]:=i; done:=false; i:=0; while (not done) do begin if i