Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 
 

418 righe
19 KiB

  1. unit ulibShaderFile;
  2. {$IFDEF fpc}
  3. {$mode objfpc}{$H+}
  4. {$ENDIF}
  5. interface
  6. uses
  7. Classes, SysUtils, Variants;
  8. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. type
  10. {$Z4}
  11. TlsfLogLevel = (
  12. llDebug = 0,
  13. llInfo = 1,
  14. llWarning = 2,
  15. llError = 3
  16. );
  17. {$Z4}
  18. TlsfErrorCode = (
  19. errNone = $00000000,
  20. errNotInit = $00000001,
  21. errInvalidHandleShaderFile = $00000010,
  22. errInvalidHandleShaderGenerator = $00000011,
  23. errInvalidGeneratorName = $00000020,
  24. errInvalidPropertyIndex = $00000021,
  25. errInvalidPropertyName = $00000022,
  26. errGeneratorNotAssignedToFile = $00000023,
  27. errUnknownIdentfifier = $00001000,
  28. errDuplicateIdentifier = $00001001,
  29. errOutOfRange = $00001002,
  30. errInvalidIdentifier = $00001003,
  31. errInvalidParamterCount = $00001004,
  32. errInvalidParamter = $00001005,
  33. errUnexpectedToken = $00001006,
  34. errInvalidToken = $00001007,
  35. errExpressionInternal = $00001008,
  36. errExpression = $00001009,
  37. errShaderPartInternal = $0000100a,
  38. errShaderPart = $0000100b,
  39. errInvalidLibraryName = $00002000,
  40. errInvalidLibraryHandle = $00002001,
  41. errInvalidMethodName = $00002002,
  42. errUnknown = -1
  43. );
  44. TlsfShaderFileHandle = Pointer;
  45. TlsfGeneratorHandle = Pointer;
  46. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  47. TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar; const aUserArgs: Pointer); stdcall;
  48. Tlsf_ShaderFile_create = function: TlsfShaderFileHandle; stdcall;
  49. Tlsf_ShaderFile_setLogCallback = function(const aHandle: TlsfShaderFileHandle; const aCallback: TlsfShaderFileLogEvent; const aUserArgs: Pointer): TlsfErrorCode; stdcall;
  50. Tlsf_ShaderFile_loadFromFile = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall;
  51. Tlsf_ShaderFile_saveToFile = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall;
  52. Tlsf_ShaderFile_getGeneratorNames = function(const aHandle: TlsfShaderFileHandle): PAnsiChar; stdcall;
  53. Tlsf_ShaderFile_destroy = function(const aHandle: TlsfShaderFileHandle): TlsfErrorCode; stdcall;
  54. Tlsf_Generator_create = function(const aHandle: TlsfShaderFileHandle; const aName: PAnsiChar): TlsfGeneratorHandle; stdcall;
  55. Tlsf_Generator_getPropertyNames = function(const aHandle: TlsfGeneratorHandle): PAnsiChar; stdcall;
  56. Tlsf_Generator_getProperty = function(const aHandle: TlsfGeneratorHandle; const aIndex: Integer): PAnsiChar; stdcall;
  57. Tlsf_Generator_getPropertyByName = function(const aHandle: TlsfGeneratorHandle; const aName: PAnsiChar): PAnsiChar; stdcall;
  58. Tlsf_Generator_setProperty = function(const aHandle: TlsfGeneratorHandle; const aIndex: Integer; const aValue: PAnsiChar): TlsfErrorCode; stdcall;
  59. Tlsf_Generator_setPropertyByName = function(const aHandle: TlsfGeneratorHandle; const aName: PAnsiChar; const aValue: PAnsiChar): TlsfErrorCode; stdcall;
  60. Tlsf_Generator_generateCode = function(const aHandle: TlsfGeneratorHandle): PAnsiChar; stdcall;
  61. Tlsf_Generator_destroy = function(const aHandle: TlsfGeneratorHandle): TlsfErrorCode; stdcall;
  62. Tlsf_init = function: TlsfErrorCode; stdcall;
  63. Tlsf_getLastErrorCode = function: TlsfErrorCode; stdcall;
  64. Tlsf_getLastErrorMsg = function: PAnsiChar; stdcall;
  65. Tlsf_getLastErrorTrace = function: PAnsiChar; stdcall;
  66. Tlsf_finish = function: TlsfErrorCode; stdcall;
  67. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  68. TlsfShaderFile = class(TObject)
  69. private
  70. fHandle: TlsfShaderFileHandle;
  71. protected
  72. procedure LogMsg(const aLogLevel: TlsfLogLevel; const aMsg: String); virtual;
  73. public
  74. property Handle: TlsfShaderFileHandle read fHandle;
  75. procedure LoadFromFile(const aFilename: String);
  76. procedure SaveToFile(const aFilename: String);
  77. constructor Create;
  78. destructor Destroy; override;
  79. end;
  80. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  81. TlsfGenerator = class(TObject)
  82. private
  83. fName: String;
  84. fHandle: TlsfGeneratorHandle;
  85. fShaderFile: TlsfShaderFile;
  86. fProperties: TStringList;
  87. function GetProperties: TStrings;
  88. public
  89. property Name: String read fName;
  90. property ShaderFile: TlsfShaderFile read fShaderFile;
  91. property Properties: TStrings read GetProperties;
  92. function GetProperty(const aName: String): Variant; overload;
  93. function GetProperty(const aIndex: Integer): Variant; overload;
  94. procedure SetProperty(const aName: String; const aValue: Variant); overload;
  95. procedure SetProperty(const aIndex: Integer; const aValue: Variant); overload;
  96. function GenerateCode: String;
  97. constructor Create(const aShaderFile: TlsfShaderFile; const aName: String);
  98. destructor Destroy; override;
  99. end;
  100. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  101. TlsfException = class(Exception)
  102. private
  103. fErrorCode: TlsfErrorCode;
  104. public
  105. property ErrorCode: TlsfErrorCode read fErrorCode;
  106. constructor Create(const aMsg: string; const aError: TlsfErrorCode = errNone);
  107. end;
  108. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  109. var
  110. lsf_ShaderFile_create: Tlsf_ShaderFile_create;
  111. lsf_ShaderFile_setLogCallback: Tlsf_ShaderFile_setLogCallback;
  112. lsf_ShaderFile_loadFromFile: Tlsf_ShaderFile_loadFromFile;
  113. lsf_ShaderFile_saveToFile: Tlsf_ShaderFile_saveToFile;
  114. lsf_ShaderFile_getGeneratorNames: Tlsf_ShaderFile_getGeneratorNames;
  115. lsf_ShaderFile_destroy: Tlsf_ShaderFile_destroy;
  116. lsf_Generator_create: Tlsf_Generator_create;
  117. lsf_Generator_getPropertyNames: Tlsf_Generator_getPropertyNames;
  118. lsf_Generator_getProperty: Tlsf_Generator_getProperty;
  119. lsf_Generator_getPropertyByName: Tlsf_Generator_getPropertyByName;
  120. lsf_Generator_setProperty: Tlsf_Generator_setProperty;
  121. lsf_Generator_setPropertyByName: Tlsf_Generator_setPropertyByName;
  122. lsf_Generator_generateCode: Tlsf_Generator_generateCode;
  123. lsf_Generator_destroy: Tlsf_Generator_destroy;
  124. lsf_getLastErrorCode: Tlsf_getLastErrorCode;
  125. lsf_getLastErrorMsg: Tlsf_getLastErrorMsg;
  126. lsf_getLastErrorTrace: Tlsf_getLastErrorTrace;
  127. procedure lsf_init(const aLibName: String);
  128. procedure lsf_finish;
  129. implementation
  130. uses
  131. {$IF DEFINED(WIN32) OR DEFINED(WIN64)}
  132. windows;
  133. type
  134. TLibHandle = HMODULE;
  135. function LibOpen(const aLibName: String; out aErrorCode: Cardinal): TLibHandle;
  136. begin
  137. result := LoadLibraryA(PAnsiChar(AnsiString(aLibName)));
  138. if (result = 0)
  139. then aErrorCode := GetLastError()
  140. else aErrorCode := 0;
  141. end;
  142. function GetAddr(const aLibHandle: TLibHandle; const aName: String): Pointer;
  143. begin
  144. result := GetProcAddress(aLibHandle, PAnsiChar(AnsiString(aName)));
  145. end;
  146. function LibClose(const aLibHandle: TLibHandle): Boolean;
  147. begin
  148. result := FreeLibrary(aLibHandle);
  149. end;
  150. {$ELSE}
  151. {$ERROR 'unknown operation system'}
  152. {$IFEND}
  153. var
  154. libHandle: TLibHandle;
  155. lsf_init_intern: Tlsf_init;
  156. lsf_finish_intern: Tlsf_finish;
  157. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  158. procedure lsf_init(const aLibName: String);
  159. function LoadProc(const aName: String): Pointer;
  160. begin
  161. result := GetAddr(libHandle, aName);
  162. if not Assigned(result) then
  163. raise Exception.CreateFmt('unable to load ''%s'' from ''%s''', [aName, aLibName]);
  164. end;
  165. var
  166. e: Cardinal;
  167. err: TlsfErrorCode;
  168. begin
  169. libHandle := LibOpen(aLibName, e);
  170. if (libHandle = 0) then
  171. raise Exception.CreateFmt('unable to load library (%d): %s', [e, aLibName]);
  172. lsf_ShaderFile_create := Tlsf_ShaderFile_create( LoadProc('lsf_ShaderFile_create'));
  173. lsf_ShaderFile_setLogCallback := Tlsf_ShaderFile_setLogCallback( LoadProc('lsf_ShaderFile_setLogCallback'));
  174. lsf_ShaderFile_loadFromFile := Tlsf_ShaderFile_loadFromFile( LoadProc('lsf_ShaderFile_loadFromFile'));
  175. lsf_ShaderFile_saveToFile := Tlsf_ShaderFile_saveToFile( LoadProc('lsf_ShaderFile_saveToFile'));
  176. lsf_ShaderFile_getGeneratorNames := Tlsf_ShaderFile_getGeneratorNames( LoadProc('lsf_ShaderFile_getGeneratorNames'));
  177. lsf_ShaderFile_destroy := Tlsf_ShaderFile_destroy( LoadProc('lsf_ShaderFile_destroy'));
  178. lsf_Generator_create := Tlsf_Generator_create( LoadProc('lsf_Generator_create'));
  179. lsf_Generator_getPropertyNames := Tlsf_Generator_getPropertyNames( LoadProc('lsf_Generator_getPropertyNames'));
  180. lsf_Generator_getProperty := Tlsf_Generator_getProperty( LoadProc('lsf_Generator_getProperty'));
  181. lsf_Generator_getPropertyByName := Tlsf_Generator_getPropertyByName( LoadProc('lsf_Generator_getPropertyByName'));
  182. lsf_Generator_setProperty := Tlsf_Generator_setProperty( LoadProc('lsf_Generator_setProperty'));
  183. lsf_Generator_setPropertyByName := Tlsf_Generator_setPropertyByName( LoadProc('lsf_Generator_setPropertyByName'));
  184. lsf_Generator_generateCode := Tlsf_Generator_generateCode( LoadProc('lsf_Generator_generateCode'));
  185. lsf_Generator_destroy := Tlsf_Generator_destroy( LoadProc('lsf_Generator_destroy'));
  186. lsf_init_intern := Tlsf_init( LoadProc('lsf_init'));
  187. lsf_getLastErrorCode := Tlsf_getLastErrorCode( LoadProc('lsf_getLastErrorCode'));
  188. lsf_getLastErrorMsg := Tlsf_getLastErrorMsg( LoadProc('lsf_getLastErrorMsg'));
  189. lsf_getLastErrorTrace := Tlsf_getLastErrorTrace( LoadProc('lsf_getLastErrorTrace'));
  190. lsf_finish_intern := Tlsf_finish( LoadProc('lsf_finish'));
  191. err := lsf_init_intern();
  192. if (err <> errNone) then
  193. raise TlsfException.Create('error while initializing library: ' + lsf_getLastErrorMsg(), err);
  194. end;
  195. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  196. procedure lsf_finish;
  197. begin
  198. lsf_finish_intern();
  199. lsf_ShaderFile_create := nil;
  200. lsf_ShaderFile_setLogCallback := nil;
  201. lsf_ShaderFile_loadFromFile := nil;
  202. lsf_ShaderFile_saveToFile := nil;
  203. lsf_ShaderFile_getGeneratorNames := nil;
  204. lsf_ShaderFile_destroy := nil;
  205. lsf_getLastErrorCode := nil;
  206. lsf_getLastErrorMsg := nil;
  207. lsf_getLastErrorTrace := nil;
  208. if (libHandle <> 0) then begin
  209. LibClose(libHandle);
  210. libHandle := 0;
  211. end;
  212. end;
  213. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  214. procedure LogCallback(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar; const aUserArgs: Pointer); stdcall;
  215. begin
  216. TlsfShaderFile(aUserArgs).LogMsg(aLogLevel, String(aMsg));
  217. end;
  218. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  219. //TlsfShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  220. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  221. procedure TlsfShaderFile.LogMsg(const aLogLevel: TlsfLogLevel; const aMsg: String);
  222. begin
  223. // DUMMY
  224. end;
  225. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  226. procedure TlsfShaderFile.LoadFromFile(const aFilename: String);
  227. var
  228. err: TlsfErrorCode;
  229. begin
  230. err := lsf_ShaderFile_loadFromFile(fHandle, PAnsiChar(AnsiString(aFilename)));
  231. if (err <> errNone) then
  232. raise TlsfException.Create('error while loading from file: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode());
  233. end;
  234. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  235. procedure TlsfShaderFile.SaveToFile(const aFilename: String);
  236. var
  237. err: TlsfErrorCode;
  238. begin
  239. err := lsf_ShaderFile_saveToFile(fHandle, PAnsiChar(AnsiString(aFilename)));
  240. if (err <> errNone) then
  241. raise TlsfException.Create('error while saving to file: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode());
  242. end;
  243. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  244. constructor TlsfShaderFile.Create;
  245. var
  246. err: TlsfErrorCode;
  247. begin
  248. inherited Create;
  249. fHandle := lsf_ShaderFile_create();
  250. if not Assigned(fHandle) then
  251. raise TlsfException.Create('error while creating shader file: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode());
  252. err := lsf_ShaderFile_setLogCallback(fHandle, @LogCallback, self);
  253. if (err <> errNone) then
  254. raise TlsfException.Create('error while settings log callback: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode());
  255. end;
  256. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  257. destructor TlsfShaderFile.Destroy;
  258. begin
  259. if Assigned(fHandle) then begin
  260. lsf_ShaderFile_destroy(fHandle);
  261. fHandle := nil;
  262. end;
  263. inherited Destroy;
  264. end;
  265. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  266. //TlsfGenerator/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  267. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  268. function TlsfGenerator.GetProperties: TStrings;
  269. begin
  270. result := fProperties;
  271. end;
  272. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  273. function TlsfGenerator.GetProperty(const aName: String): Variant;
  274. var
  275. s: PAnsiChar;
  276. begin
  277. s := lsf_Generator_getPropertyByName(fHandle, PAnsiChar(AnsiString(aName)));
  278. if not Assigned(s) then
  279. raise TlsfException.Create('error while getting property by name: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode());
  280. result := String(s);
  281. end;
  282. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  283. function TlsfGenerator.GetProperty(const aIndex: Integer): Variant;
  284. var
  285. s: PAnsiChar;
  286. begin
  287. s := lsf_Generator_getProperty(fHandle, aIndex);
  288. if not Assigned(s) then
  289. raise TlsfException.Create('error while getting property by index: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode());
  290. result := String(s);
  291. end;
  292. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  293. procedure TlsfGenerator.SetProperty(const aName: String; const aValue: Variant);
  294. var
  295. err: TlsfErrorCode;
  296. s: AnsiString;
  297. begin
  298. s := AnsiString(aValue);
  299. err := lsf_Generator_setPropertyByName(fHandle, PAnsiChar(AnsiString(aName)), PAnsiChar(s));
  300. if (err <> errNone) then
  301. raise TlsfException.Create('error while settings property by name: ' + lsf_getLastErrorMsg(), err);
  302. end;
  303. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  304. procedure TlsfGenerator.SetProperty(const aIndex: Integer; const aValue: Variant);
  305. var
  306. err: TlsfErrorCode;
  307. s: AnsiString;
  308. begin
  309. s := AnsiString(aValue);
  310. err := lsf_Generator_setProperty(fHandle, aIndex, PAnsiChar(s));
  311. if (err <> errNone) then
  312. raise TlsfException.Create('error while settings property by name: ' + lsf_getLastErrorMsg(), err);
  313. end;
  314. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  315. function TlsfGenerator.GenerateCode: String;
  316. var
  317. s: PAnsiChar;
  318. begin
  319. s := lsf_Generator_generateCode(fHandle);
  320. if not Assigned(s) then
  321. raise TlsfException.Create('error while generating code: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode());
  322. result := String(s);
  323. end;
  324. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  325. constructor TlsfGenerator.Create(const aShaderFile: TlsfShaderFile; const aName: String);
  326. var
  327. s: PAnsiChar;
  328. begin
  329. inherited Create;
  330. fProperties := TStringList.Create;
  331. fShaderFile := aShaderFile;
  332. fName := aName;
  333. fHandle := lsf_Generator_create(fShaderFile.Handle, PAnsiChar(AnsiString(aName)));
  334. if not Assigned(fHandle) then
  335. raise TlsfException.Create('error while opening generator: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode());
  336. s := lsf_Generator_getPropertyNames(fHandle);
  337. if not Assigned(s) then
  338. raise TlsfException.Create('error while generating code: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode());
  339. fProperties.Text := string(s);
  340. end;
  341. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  342. destructor TlsfGenerator.Destroy;
  343. begin
  344. if Assigned(fHandle) then begin
  345. lsf_Generator_destroy(fHandle);
  346. fHandle := nil;
  347. end;
  348. FreeAndNil(fProperties);
  349. inherited Destroy;
  350. end;
  351. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  352. //TlsfException/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  353. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  354. constructor TlsfException.Create(const aMsg: string; const aError: TlsfErrorCode);
  355. begin
  356. inherited Create(aMsg);
  357. fErrorCode := aError;
  358. end;
  359. end.