From f366f88a8b69a9ad8916ed34cae291996add7195 Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Sun, 13 Sep 2015 19:19:49 +0200 Subject: [PATCH] * implemented header file and simple example for c * implementation of library almost finished * fixed some small compiler warnings --- header/c/example/test.c | 78 ++++++ header/c/libShaderFile.c | 91 +++++++ header/c/libShaderFile.h | 88 +++++++ header/delphi/ulibShaderFile.pas | 155 ++++++++++++ header/ulibShaderFile.pas | 126 ---------- libShaderFile.lpi | 149 ++++++++++- libShaderFile.lpr | 417 +++++++++++++++++++++++++++++-- 7 files changed, 953 insertions(+), 151 deletions(-) create mode 100644 header/c/example/test.c create mode 100644 header/c/libShaderFile.c create mode 100644 header/c/libShaderFile.h create mode 100644 header/delphi/ulibShaderFile.pas delete mode 100644 header/ulibShaderFile.pas diff --git a/header/c/example/test.c b/header/c/example/test.c new file mode 100644 index 0000000..5d79863 --- /dev/null +++ b/header/c/example/test.c @@ -0,0 +1,78 @@ +#include +#include "../libShaderFile.h" + +int main(int argc, char **argv) +{ + lsf_shader_file_handle_t sfHandle = 0; + lsf_shader_generator_handle_t sgHandle = 0; + lsf_error_code_t err = LSF_ERR_NONE; + int ret = 0, i = 3; + const char* code = NULL; + + if (argc < 3) + { + printf("error: expected input file and generator/class name as parameter\n"); + return 1; + } + + lsf_init("../../library/libShaderFile-i386-win32.dll"); + + // create shader file + sfHandle = lsf_shader_file_create(); + if (!sfHandle) + { + printf("unable to create shader file: %s\n", lsf_get_last_error_msg()); + ret = 2; + goto cleanup_lib; + } + + // load shader file + err = lsf_shader_file_load_from_file(sfHandle, argv[1]); + if (err != LSF_ERR_NONE) + { + printf("unable to load shader file: %s\n", lsf_get_last_error_msg()); + ret = 3; + goto cleanup_shader_file; + } + + // create generator + sgHandle = lsf_generator_create(sfHandle, argv[2]); + if (!sgHandle) + { + printf("unable to create generator: %s\n", lsf_get_last_error_msg()); + ret = 4; + goto cleanup_shader_file; + } + + // apply properties + while (i < argc-1) + { + err = lsf_generator_set_property_by_name(sgHandle, argv[i], argv[i+1]); + if (err != LSF_ERR_NONE) + { + printf("unable to set property (%s=%s) (err=0x%08x)", argv[i], argv[i+1], err); + ret = 5; + goto cleanup_shader_generator; + } + i += 2; + } + + // generate code + code = lsf_generator_generate_code(sgHandle); + if (!code) + { + printf("unable to generate code: %s\n", lsf_get_last_error_msg()); + ret = 4; + goto cleanup_shader_generator; + } + + printf("%s", code); + +cleanup_shader_generator: + lsf_generator_destroy(sgHandle); +cleanup_shader_file: + lsf_shader_file_destroy(sfHandle); +cleanup_lib: + lsf_finish(); + return ret; +} \ No newline at end of file diff --git a/header/c/libShaderFile.c b/header/c/libShaderFile.c new file mode 100644 index 0000000..f5c9130 --- /dev/null +++ b/header/c/libShaderFile.c @@ -0,0 +1,91 @@ +#include "libShaderFile.h" + +//#define LSF_DEBUG +#ifdef LSF_DEBUG +# include +#endif + +#if defined(WIN32) || defined(WIN64) +# include + +typedef HMODULE lib_handle_t; + +lib_handle_t open_lib(const char* name) + { return LoadLibrary(name); }; + +void* get_addr(lib_handle_t handle, const char* name) + { return GetProcAddress(handle, name); }; + +int close_lib(lib_handle_t handle) + { return FreeLibrary(handle); }; + +#elif defined(LINUX) +# include +# error "linux is not supported yet" +#else +# error "unknown operation system" +#endif + +lib_handle_t handle = NULL; +lsf_init_t lsf_init_intern = NULL; +lsf_finish_t lsf_finish_intern = NULL; + +#ifndef LSF_DEBUG +# define LoadProc(proc, name) \ + proc = get_addr(handle, name); \ + if (!proc) \ + return LSF_ERR_INVALID_METHOD_NAME +#else +# define LoadProc(proc, name) \ + proc = get_addr(handle, name); \ + printf("load method '%s' (addr=0x%016x)\n", name, proc); \ + if (!proc) \ + return LSF_ERR_INVALID_METHOD_NAME +#endif + +int lsf_init(const char* libname) +{ +#ifdef LSF_DEBUG + printf("loading library '%s'\n", libname); +#endif + + handle = open_lib(libname); + if (!handle) + return LSF_ERR_INVALID_LIBRARY_NAME; + +#ifdef LSF_DEBUG + printf(" done (handle=0x%016x)\n", handle); +#endif + + LoadProc(lsf_shader_file_create, "lsf_ShaderFile_create"); + LoadProc(lsf_shader_file_set_log_callback, "lsf_ShaderFile_setLogCallback"); + LoadProc(lsf_shader_file_load_from_file, "lsf_ShaderFile_loadFromFile"); + LoadProc(lsf_shader_file_save_to_file, "lsf_ShaderFile_saveToFile"); + LoadProc(lsf_shader_file_get_generator_names, "lsf_ShaderFile_getGeneratorNames"); + LoadProc(lsf_shader_file_destroy, "lsf_ShaderFile_destroy"); + + LoadProc(lsf_generator_create, "lsf_Generator_create"); + LoadProc(lsf_generator_get_property_names, "lsf_Generator_getPropertyNames"); + LoadProc(lsf_generator_get_property, "lsf_Generator_getProperty"); + LoadProc(lsf_generator_get_property_by_name, "lsf_Generator_getPropertyByName"); + LoadProc(lsf_generator_set_property, "lsf_Generator_setProperty"); + LoadProc(lsf_generator_set_property_by_name, "lsf_Generator_setPropertyByName"); + LoadProc(lsf_generator_generate_code, "lsf_Generator_generateCode"); + LoadProc(lsf_generator_destroy, "lsf_Generator_destroy"); + + LoadProc(lsf_init_intern, "lsf_init"); + LoadProc(lsf_get_last_error_code, "lsf_getLastErrorCode"); + LoadProc(lsf_get_last_error_msg, "lsf_getLastErrorMsg"); + LoadProc(lsf_get_last_error_trace, "lsf_getLastErrorTrace"); + LoadProc(lsf_finish_intern, "lsf_finish"); + + return lsf_init_intern(); +} + +int lsf_finish(void) +{ + lsf_error_code_t err = lsf_finish_intern(); + if (!close_lib(handle)) + return LSF_ERR_INVALID_LIBRARY_HANDLE; + return err; +} diff --git a/header/c/libShaderFile.h b/header/c/libShaderFile.h new file mode 100644 index 0000000..57e3bb6 --- /dev/null +++ b/header/c/libShaderFile.h @@ -0,0 +1,88 @@ +#ifndef LIB_SHADER_FILE_H +#define LIB_SHADER_FILE_H + +#include + +#define LSF_LOGLEVEL_DEBUG 0 +#define LSF_LOGLEVEL_INFO 1 +#define LSF_LOGLEVEL_WARNING 2 +#define LSF_LOGLEVEL_ERROR 3 + +#define LSF_ERR_NONE 0x00000000 +#define LSF_ERR_NOT_INIT 0x00000001 +#define LSF_ERR_INVALID_HANDLE_SHADER_FILE 0x00000010 +#define LSF_ERR_INVALID_HANDLE_SHADER_GENERATOR 0x00000011 +#define LSF_ERR_INVALID_GENERATOR_NAME 0x00000020 +#define LSF_ERR_INVALID_PROPERTY_INDEX 0x00000021 +#define LSF_ERR_INVALID_PROPERTY_NAME 0x00000022 +#define LSF_ERR_UNKNOWN_IDENTFIFIER 0x00001000 +#define LSF_ERR_DUPLICATE_IDENTIFIER 0x00001001 +#define LSF_ERR_OUT_OF_RANGE 0x00001002 +#define LSF_ERR_INVALID_IDENTIFIER 0x00001003 +#define LSF_ERR_INVALID_PARAMTER_COUNT 0x00001004 +#define LSF_ERR_INVALID_PARAMTER 0x00001005 +#define LSF_ERR_UNEXPECTED_TOKEN 0x00001006 +#define LSF_ERR_INVALID_TOKEN 0x00001007 +#define LSF_ERR_EXPRESSION_INTERNAL 0x00001008 +#define LSF_ERR_EXPRESSION 0x00001009 +#define LSF_ERR_SHADER_PART_INTERNAL 0x0000100A +#define LSF_ERR_SHADER_PART 0x0000100B +#define LSF_ERR_INVALID_LIBRARY_NAME 0x00002000 +#define LSF_ERR_INVALID_LIBRARY_HANDLE 0x00002001 +#define LSF_ERR_INVALID_METHOD_NAME 0x00002002 +#define LSF_ERR_UNKNOWN 0xFFFFFFFF + +#define WINAPI __stdcall + +typedef uint32_t lsf_error_code_t; +typedef uint32_t lsf_log_level_t; +typedef void* lsf_shader_file_handle_t; +typedef void* lsf_shader_generator_handle_t; +typedef void (*lsf_shader_file_log_callback_t)(const lsf_log_level_t loglevel, const char* msg, const void* userargs); + +typedef lsf_shader_file_handle_t (WINAPI *lsf_shader_file_create_t) (); +typedef lsf_error_code_t (WINAPI *lsf_shader_file_set_log_callback_t) (const lsf_shader_file_handle_t handle, const lsf_shader_file_log_callback_t callback, const void* userargs); +typedef lsf_error_code_t (WINAPI *lsf_shader_file_load_from_file_t) (const lsf_shader_file_handle_t handle, const char* filename); +typedef lsf_error_code_t (WINAPI *lsf_shader_file_save_to_file_t) (const lsf_shader_file_handle_t handle, const char* filename); +typedef const char* (WINAPI *lsf_shader_file_get_generator_names_t) (const lsf_shader_file_handle_t handle); +typedef lsf_error_code_t (WINAPI *lsf_shader_file_destroy_t) (const lsf_shader_file_handle_t handle); + +typedef lsf_shader_generator_handle_t (WINAPI *lsf_generator_create_t) (const lsf_shader_file_handle_t handle, const char* name); +typedef const char* (WINAPI *lsf_generator_get_property_names_t) (const lsf_shader_generator_handle_t handle); +typedef const char* (WINAPI *lsf_generator_get_property_t) (const lsf_shader_generator_handle_t handle, const int index); +typedef const char* (WINAPI *lsf_generator_get_property_by_name_t) (const lsf_shader_generator_handle_t handle, const char* name); +typedef lsf_error_code_t (WINAPI *lsf_generator_set_property_t) (const lsf_shader_generator_handle_t handle, const int index, const char* value); +typedef lsf_error_code_t (WINAPI *lsf_generator_set_property_by_name_t) (const lsf_shader_generator_handle_t handle, const char* name, const char* value); +typedef const char* (WINAPI *lsf_generator_generate_code_t) (const lsf_shader_generator_handle_t handle); +typedef lsf_error_code_t (WINAPI *lsf_generator_destroy_t) (const lsf_shader_generator_handle_t handle); + +typedef lsf_error_code_t (WINAPI *lsf_init_t) (); +typedef lsf_error_code_t (WINAPI *lsf_get_last_error_code_t) (); +typedef const char* (WINAPI *lsf_get_last_error_msg_t) (); +typedef const char* (WINAPI *lsf_get_last_error_trace_t) (); +typedef lsf_error_code_t (WINAPI *lsf_finish_t) (); + +lsf_shader_file_create_t lsf_shader_file_create; +lsf_shader_file_set_log_callback_t lsf_shader_file_set_log_callback; +lsf_shader_file_load_from_file_t lsf_shader_file_load_from_file; +lsf_shader_file_save_to_file_t lsf_shader_file_save_to_file; +lsf_shader_file_get_generator_names_t lsf_shader_file_get_generator_names; +lsf_shader_file_destroy_t lsf_shader_file_destroy; + +lsf_generator_create_t lsf_generator_create; +lsf_generator_get_property_names_t lsf_generator_get_property_names; +lsf_generator_get_property_t lsf_generator_get_property; +lsf_generator_get_property_by_name_t lsf_generator_get_property_by_name; +lsf_generator_set_property_t lsf_generator_set_property; +lsf_generator_set_property_by_name_t lsf_generator_set_property_by_name; +lsf_generator_generate_code_t lsf_generator_generate_code; +lsf_generator_destroy_t lsf_generator_destroy; + +lsf_get_last_error_code_t lsf_get_last_error_code; +lsf_get_last_error_msg_t lsf_get_last_error_msg; +lsf_get_last_error_trace_t lsf_get_last_error_trace; + +int lsf_init(const char* libname); +int lsf_finish(void); + +#endif /* LIB_SHADER_FILE_H */ \ No newline at end of file diff --git a/header/delphi/ulibShaderFile.pas b/header/delphi/ulibShaderFile.pas new file mode 100644 index 0000000..8f08d4d --- /dev/null +++ b/header/delphi/ulibShaderFile.pas @@ -0,0 +1,155 @@ +unit ulibShaderFile; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const + LSF_LOGLEVEL_DEBUG = 0; + LSF_LOGLEVEL_INFO = 1; + LSF_LOGLEVEL_WARNING = 2; + LSF_LOGLEVEL_ERROR = 3; + + LSF_ERR_NONE = $00000000; + LSF_ERR_NOT_INIT = $00000001; + LSF_ERR_INVALID_HANDLE_SHADER_FILE = $00000010; + LSF_ERR_INVALID_HANDLE_SHADER_GENERATOR = $00000011; + LSF_ERR_INVALID_GENERATOR_NAME = $00000020; + LSF_ERR_INVALID_PROPERTY_INDEX = $00000021; + LSF_ERR_UNKNOWN_IDENTFIFIER = $00001000; + LSF_ERR_DUPLICATE_IDENTIFIER = $00001001; + LSF_ERR_OUT_OF_RANGE = $00001002; + LSF_ERR_INVALID_IDENTIFIER = $00001003; + LSF_ERR_INVALID_PARAMTER_COUNT = $00001004; + LSF_ERR_INVALID_PARAMTER = $00001005; + LSF_ERR_UNEXPECTED_TOKEN = $00001006; + LSF_ERR_INVALID_TOKEN = $00001007; + LSF_ERR_EXPRESSION_INTERNAL = $00001008; + LSF_ERR_EXPRESSION = $00001009; + LSF_ERR_SHADER_PART_INTERNAL = $0000100A; + LSF_ERR_SHADER_PART = $0000100B; + LSF_ERR_UNKNOWN = $FFFFFFFF; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +type + TlsfErrorCode = Cardinal; + TlsfLogLevel = Cardinal; + TlsfShaderFileHandle = Pointer; + TlsfShaderGeneratorHandle = Pointer; + TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar; const aUserArgs: Pointer); + + Tlsf_ShaderFile_create = function: TlsfShaderFileHandle; stdcall; + Tlsf_ShaderFile_setLogCallback = function(const aHandle: TlsfShaderFileHandle; const aCallback: TlsfShaderFileLogEvent; const aUserArgs: Pointer): TlsfErrorCode; stdcall; + Tlsf_ShaderFile_loadFromFile = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall; + Tlsf_ShaderFile_saveToFile = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall; + Tlsf_ShaderFile_getGeneratorNames = function(const aHandle: TlsfShaderFileHandle): PAnsiChar; stdcall; + Tlsf_ShaderFile_destroy = function(const aHandle: TlsfShaderFileHandle): TlsfErrorCode; stdcall; + + Tlsf_Generator_create = function(const aHandle: TlsfShaderFileHandle; const aName: PAnsiChar): TlsfShaderGeneratorHandle; stdcall; + Tlsf_Generator_getPropertyNames = function(const aHandle: TlsfShaderGeneratorHandle): PAnsiChar; stdcall; + Tlsf_Generator_getProperty = function(const aHandle: TlsfShaderGeneratorHandle; const aIndex: Integer): PAnsiChar; stdcall; + Tlsf_Generator_setProperty = function(const aHandle: TlsfShaderGeneratorHandle; const aIndex: Integer; const aValue: PAnsiChar): TlsfErrorCode; stdcall; + Tlsf_Generator_generateCode = function(const aHandle: TlsfShaderGeneratorHandle): PAnsiChar; stdcall; + Tlsf_Generator_destroy = function(const aHandle: TlsfShaderGeneratorHandle): TlsfErrorCode; stdcall; + + Tlsf_init = function : TlsfErrorCode; stdcall; + Tlsf_getLastErrorCode = function : TlsfErrorCode; stdcall; + Tlsf_getLastErrorMsg = function : PAnsiChar; stdcall; + Tlsf_getLastErrorTrace = function : PAnsiChar; stdcall; + Tlsf_finish = function: TlsfErrorCode; stdcall; + +var + lsf_ShaderFile_create: Tlsf_ShaderFile_create; + lsf_ShaderFile_setLogCallback: Tlsf_ShaderFile_setLogCallback; + lsf_ShaderFile_loadFromFile: Tlsf_ShaderFile_loadFromFile; + lsf_ShaderFile_saveToFile: Tlsf_ShaderFile_saveToFile; + lsf_ShaderFile_getGeneratorNames: Tlsf_ShaderFile_getGeneratorNames; + lsf_ShaderFile_destroy: Tlsf_ShaderFile_destroy; + + lsf_Generator_create: Tlsf_Generator_create; + lsf_Generator_getPropertyNames: Tlsf_Generator_getPropertyNames; + lsf_Generator_getProperty: Tlsf_Generator_getProperty; + lsf_Generator_setProperty: Tlsf_Generator_setProperty; + lsf_Generator_generateCode: Tlsf_Generator_generateCode; + lsf_Generator_destroy: Tlsf_Generator_destroy; + + lsf_getLastErrorCode: Tlsf_getLastErrorCode; + lsf_getLastErrorMsg: Tlsf_getLastErrorMsg; + lsf_getLastErrorTrace: Tlsf_getLastErrorTrace; + +procedure lsf_init(const aLibName: String); +procedure lsf_finish; + +implementation + +uses + dynlibs; + +var + libHandle: TLibHandle; + lsf_init_intern: Tlsf_init; + lsf_finish_intern: Tlsf_finish; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure lsf_init(const aLibName: String); + + function LoadProc(const aName: AnsiString): Pointer; + begin + result := GetProcedureAddress(libHandle, aName); + if not Assigned(result) then + raise Exception.CreateFmt('unable to load ''%s'' from ''%s''', [aName, aLibName]); + end; + +begin + libHandle := LoadLibrary(aLibName); + if (libHandle = 0) then + raise Exception.CreateFmt('unable to load library: %s', [aLibName]); + lsf_ShaderFile_create := Tlsf_ShaderFile_create( LoadProc('lsf_ShaderFile_create')); + lsf_ShaderFile_setLogCallback := Tlsf_ShaderFile_setLogCallback( LoadProc('lsf_ShaderFile_setLogCallback')); + lsf_ShaderFile_loadFromFile := Tlsf_ShaderFile_loadFromFile( LoadProc('lsf_ShaderFile_loadFromFile')); + lsf_ShaderFile_saveToFile := Tlsf_ShaderFile_saveToFile( LoadProc('lsf_ShaderFile_saveToFile')); + lsf_ShaderFile_getGeneratorNames := Tlsf_ShaderFile_getGeneratorNames( LoadProc('lsf_ShaderFile_getGeneratorNames')); + lsf_ShaderFile_destroy := Tlsf_ShaderFile_destroy( LoadProc('lsf_ShaderFile_destroy')); + + lsf_Generator_create := Tlsf_Generator_create( LoadProc('lsf_Generator_create')); + lsf_Generator_getPropertyNames := Tlsf_Generator_getPropertyNames( LoadProc('lsf_Generator_getPropertyNames')); + lsf_Generator_getProperty := Tlsf_Generator_getProperty( LoadProc('lsf_Generator_getProperty')); + lsf_Generator_setProperty := Tlsf_Generator_setProperty( LoadProc('lsf_Generator_setProperty')); + lsf_Generator_generateCode := Tlsf_Generator_generateCode( LoadProc('lsf_Generator_generateCode')); + lsf_Generator_destroy := Tlsf_Generator_destroy( LoadProc('lsf_Generator_destroy')); + + lsf_init_intern := Tlsf_init( LoadProc('lsf_init')); + lsf_getLastErrorCode := Tlsf_getLastErrorCode( LoadProc('lsf_getLastErrorCode')); + lsf_getLastErrorMsg := Tlsf_getLastErrorMsg( LoadProc('lsf_getLastErrorMsg')); + lsf_getLastErrorTrace := Tlsf_getLastErrorTrace( LoadProc('lsf_getLastErrorTrace')); + lsf_finish_intern := Tlsf_finish( LoadProc('lsf_finish')); + + if (lsf_init_intern() <> LSF_ERR_NONE) then + raise Exception.Create('error while initializing library: ' + lsf_getLastErrorMsg()); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure lsf_finish; +begin + lsf_finish_intern(); + lsf_ShaderFile_create := nil; + lsf_ShaderFile_setLogCallback := nil; + lsf_ShaderFile_loadFromFile := nil; + lsf_ShaderFile_saveToFile := nil; + lsf_ShaderFile_getGeneratorNames := nil; + lsf_ShaderFile_destroy := nil; + lsf_getLastErrorCode := nil; + lsf_getLastErrorMsg := nil; + lsf_getLastErrorTrace := nil; + if (libHandle <> 0) then begin + FreeLibrary(libHandle); + libHandle := 0; + end; +end; + +end. + diff --git a/header/ulibShaderFile.pas b/header/ulibShaderFile.pas deleted file mode 100644 index 8e3b5bd..0000000 --- a/header/ulibShaderFile.pas +++ /dev/null @@ -1,126 +0,0 @@ -unit ulibShaderFile; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -const - LSF_LOGLEVEL_DEBUG = 0; - LSF_LOGLEVEL_INFO = 1; - LSF_LOGLEVEL_WARNING = 2; - LSF_LOGLEVEL_ERROR = 3; - - LSF_ERR_NONE = $00000000; - LSF_ERR_NOT_INIT = $00000001; - LSF_ERR_INVALID_HANDLE_SHADER_FILE = $00000002; - LSF_ERR_UNKNOWN_IDENTFIFIER = $00001000; - LSF_ERR_DUPLICATE_IDENTIFIER = $00001001; - LSF_ERR_OUT_OF_RANGE = $00001002; - LSF_ERR_INVALID_IDENTIFIER = $00001003; - LSF_ERR_INVALID_PARAMTER_COUNT = $00001004; - LSF_ERR_INVALID_PARAMTER = $00001005; - LSF_ERR_UNEXPECTED_TOKEN = $00001006; - LSF_ERR_INVALID_TOKEN = $00001007; - LSF_ERR_EXPRESSION_INTERNAL = $00001008; - LSF_ERR_EXPRESSION = $00001009; - LSF_ERR_SHADER_PART_INTERNAL = $0000100A; - LSF_ERR_SHADER_PART = $0000100B; - LSF_ERR_UNKNOWN = $FFFFFFFF; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -type - TlsfErrorCode = Cardinal; - TlsfLogLevel = Cardinal; - TlsfShaderFileHandle = Pointer; - TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar); - - Tlsf_ShaderFile_create = function: TlsfShaderFileHandle; stdcall; - Tlsf_ShaderFile_setLogCallback = function(const aHandle: TlsfShaderFileHandle; const aCallback: TlsfShaderFileLogEvent): TlsfErrorCode; stdcall; - Tlsf_ShaderFile_loadFromFile = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall; - Tlsf_ShaderFile_saveToFile = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall; - Tlsf_ShaderFile_destroy = function(const aHandle: TlsfShaderFileHandle): TlsfErrorCode; stdcall; - - Tlsf_init = function : TlsfErrorCode; stdcall; - Tlsf_getLastErrorCode = function : TlsfErrorCode; stdcall; - Tlsf_getLastErrorMsg = function : PAnsiChar; stdcall; - Tlsf_getLastErrorTrace = function : PAnsiChar; stdcall; - Tlsf_finish = function: TlsfErrorCode; stdcall; - -var - lsf_ShaderFile_create: Tlsf_ShaderFile_create; - lsf_ShaderFile_setLogCallback: Tlsf_ShaderFile_setLogCallback; - lsf_ShaderFile_loadFromFile: Tlsf_ShaderFile_loadFromFile; - lsf_ShaderFile_saveToFile: Tlsf_ShaderFile_saveToFile; - lsf_ShaderFile_destroy: Tlsf_ShaderFile_destroy; - - lsf_getLastErrorCode: Tlsf_getLastErrorCode; - lsf_getLastErrorMsg: Tlsf_getLastErrorMsg; - lsf_getLastErrorTrace: Tlsf_getLastErrorTrace; - -procedure lsf_init(const aLibName: String); -procedure lsf_finish; - -implementation - -uses - dynlibs; - -var - libHandle: TLibHandle; - lsf_init_intern: Tlsf_init; - lsf_finish_intern: Tlsf_finish; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure lsf_init(const aLibName: String); - - function LoadProc(const aName: AnsiString): Pointer; - begin - result := GetProcedureAddress(libHandle, aName); - if not Assigned(result) then - raise Exception.CreateFmt('unable to load ''%s'' from ''%s''', [aName, aLibName]); - end; - -begin - libHandle := LoadLibrary(aLibName); - if (libHandle = 0) then - raise Exception.CreateFmt('unable to load library: %s', [aLibName]); - lsf_ShaderFile_create := Tlsf_ShaderFile_create( LoadProc('lsf_ShaderFile_create')); - lsf_ShaderFile_setLogCallback := Tlsf_ShaderFile_setLogCallback(LoadProc('lsf_ShaderFile_setLogCallback')); - lsf_ShaderFile_loadFromFile := Tlsf_ShaderFile_loadFromFile( LoadProc('lsf_ShaderFile_loadFromFile')); - lsf_ShaderFile_saveToFile := Tlsf_ShaderFile_saveToFile( LoadProc('lsf_ShaderFile_saveToFile')); - lsf_ShaderFile_destroy := Tlsf_ShaderFile_destroy( LoadProc('lsf_ShaderFile_destroy')); - - lsf_init_intern := Tlsf_init( LoadProc('lsf_init')); - lsf_getLastErrorCode := Tlsf_getLastErrorCode( LoadProc('lsf_getLastErrorCode')); - lsf_getLastErrorMsg := Tlsf_getLastErrorMsg( LoadProc('lsf_getLastErrorMsg')); - lsf_getLastErrorTrace := Tlsf_getLastErrorTrace( LoadProc('lsf_getLastErrorTrace')); - lsf_finish_intern := Tlsf_finish( LoadProc('lsf_finish')); - - if (lsf_init_intern() <> LSF_ERR_NONE) then - raise Exception.Create('error while initializing library: ' + lsf_getLastErrorMsg()); -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure lsf_finish; -begin - lsf_finish_intern(); - lsf_ShaderFile_create := nil; - lsf_ShaderFile_setLogCallback := nil; - lsf_ShaderFile_loadFromFile := nil; - lsf_ShaderFile_saveToFile := nil; - lsf_ShaderFile_destroy := nil; - lsf_getLastErrorCode := nil; - lsf_getLastErrorMsg := nil; - lsf_getLastErrorTrace := nil; - if (libHandle <> 0) then begin - FreeLibrary(libHandle); - libHandle := 0; - end; -end; - -end. - diff --git a/libShaderFile.lpi b/libShaderFile.lpi index 936f3c6..2c5fb7a 100644 --- a/libShaderFile.lpi +++ b/libShaderFile.lpi @@ -20,8 +20,127 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -35,7 +154,6 @@ - @@ -43,21 +161,44 @@ - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libShaderFile.lpr b/libShaderFile.lpr index 7faa7ff..beebb71 100644 --- a/libShaderFile.lpr +++ b/libShaderFile.lpr @@ -3,21 +3,26 @@ library libShaderFile; {$mode objfpc}{$H+} uses - SysUtils, - uengShaderFile, uengShaderPart, uengShaderFileGenerics, uengShaderFileTypes; + SysUtils, variants, + uengShaderFile, uengShaderGenerator, uengShaderPart, + uengShaderFileGenerics, uengShaderFileTypes; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //external types and contstants///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const - LSF_LOGLEVEL_DEBUG = llDebug; - LSF_LOGLEVEL_INFO = llInfo; - LSF_LOGLEVEL_WARNING = llWarning; - LSF_LOGLEVEL_ERROR = llError; + {%H-}LSF_LOGLEVEL_DEBUG = llDebug; + {%H-}LSF_LOGLEVEL_INFO = llInfo; + {%H-}LSF_LOGLEVEL_WARNING = llWarning; + {%H-}LSF_LOGLEVEL_ERROR = llError; LSF_ERR_NONE = $00000000; LSF_ERR_NOT_INIT = $00000001; - LSF_ERR_INVALID_HANDLE_SHADER_FILE = $00000002; + LSF_ERR_INVALID_HANDLE_SHADER_FILE = $00000010; + LSF_ERR_INVALID_HANDLE_SHADER_GENERATOR = $00000011; + LSF_ERR_INVALID_GENERATOR_NAME = $00000020; + LSF_ERR_INVALID_PROPERTY_INDEX = $00000021; + LSF_ERR_INVALID_PROPERTY_NAME = $00000022; LSF_ERR_UNKNOWN_IDENTFIFIER = $00001000; LSF_ERR_DUPLICATE_IDENTIFIER = $00001001; LSF_ERR_OUT_OF_RANGE = $00001002; @@ -37,25 +42,67 @@ type TlsfErrorCode = Cardinal; TlsfLogLevel = Cardinal; TlsfShaderFileHandle = Pointer; - TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar); + TlsfShaderGeneratorHandle = Pointer; + TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar; const aUserArgs: Pointer); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //internal types and contstants///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// type + TShaderFile = class; + + TPropertyMap = specialize TutlMap; + TShaderGenerator = class(TObject) + private + fOwner: TShaderFile; + fGenerator: TengShaderGenerator; + fProperties: TPropertyMap; + fPropertyNames: String; + fPropertyValue: String; + fGeneratedCode: String; + public + property Owner: TShaderFile read fOwner; + property PropertyNames: String read fPropertyNames; + property Properties: TPropertyMap read fProperties; + + function GetProperty(const aIndex: Integer): PAnsiChar; + function GetProperty(const aName: String): PAnsiChar; + function SetProperty(const aIndex: Integer; const aValue: PAnsiChar): TlsfErrorCode; + function SetProperty(const aName: String; const aValue: PAnsiChar): TlsfErrorCode; + function GenerateCode: PAnsiChar; + + constructor Create(const aOwner: TShaderFile; const aGenerator: TengShaderGenerator); + destructor Destroy; override; + end; + + TShaderGeneratorHashSet = specialize TutlHashSet; TShaderFile = class(TengShaderFile) private + fLogUserArgs: Pointer; fLogCallback: TlsfShaderFileLogEvent; + fGenerators: TShaderGeneratorHashSet; + fGeneratorNames: String; protected procedure LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); override; public - property LogCallback: TlsfShaderFileLogEvent read fLogCallback write fLogCallback; + property LogCallback: TlsfShaderFileLogEvent read fLogCallback write fLogCallback; + property LogUserArgs: Pointer read fLogUserArgs write fLogUserArgs; + property GeneratorNames: String read fGeneratorNames; + + procedure LoadFromFile(const aFilename: String); reintroduce; + + function CreateGenerator(const aName: String): TShaderGenerator; + procedure DestroyGenerator(const aGenerator: TShaderGenerator); + + constructor Create; overload; + destructor Destroy; override; end; - TengShaderFiles = specialize TutlHashSet; + TShaderFileHashSet = specialize TutlHashSet; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// var - ShaderFiles: TengShaderFiles = nil; + ShaderFiles: TShaderFileHashSet = nil; + ShaderGenerators: TShaderGeneratorHashSet = nil; LastErrorCode: TlsfErrorCode = LSF_ERR_NONE; LastErrorMsg: String = ''; LastErrorTrace: String = ''; @@ -111,7 +158,7 @@ begin try result := Assigned(ShaderFiles); if not result then - SetLastError(LSf_ERR_NOT_INIT, 'libShaderFile has not been initialized. call esf_init before using any other methods.'); + SetLastError(LSf_ERR_NOT_INIT, 'libShaderFile has not been initialized. call lsf_init before using any other methods.'); except on e: Exception do begin SetLastError(e); @@ -128,7 +175,25 @@ begin if result then begin result := ShaderFiles.Contains(TShaderFile(aHandle)); if not result then - SetLastError(LSF_ERR_INVALID_HANDLE_SHADER_FILE, Format('0x%x is not a valid shader file handle', [PtrUInt(aHandle)])); + SetLastError(LSF_ERR_INVALID_HANDLE_SHADER_FILE, Format('0x%x is not a valid shader file handle', [{%H-}PtrUInt(aHandle)])); + end; + except + on e: Exception do begin + SetLastError(e); + result := false; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function CheckShaderGeneratorHandle(const aHandle: TlsfShaderGeneratorHandle): Boolean; +begin + try + result := CheckIfInitialized; + if result then begin + result := ShaderGenerators.Contains(TShaderGenerator(aHandle)); + if not result then + SetLastError(LSF_ERR_INVALID_HANDLE_SHADER_GENERATOR, Format('0x%x is not a valid shader generator handle', [{%H-}PtrUInt(aHandle)])); end; except on e: Exception do begin @@ -142,13 +207,16 @@ end; //ShaderFile//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function lsf_ShaderFile_create: TlsfShaderFileHandle; stdcall; +var + sf: TShaderFile; begin try result := nil; if not CheckIfInitialized then exit; - result := TengShaderFile.Create; - ShaderFiles.Add(TShaderFile(result)); + sf := TShaderFile.Create; + ShaderFiles.Add(sf); + result := sf; except on e: Exception do begin SetLastError(e); @@ -158,13 +226,15 @@ begin end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function lsf_ShaderFile_setLogCallback(const aHandle: TlsfShaderFileHandle; const aCallback: TlsfShaderFileLogEvent): TlsfErrorCode; stdcall; +function lsf_ShaderFile_setLogCallback(const aHandle: TlsfShaderFileHandle; const aCallback: TlsfShaderFileLogEvent; const aUserArgs: Pointer): TlsfErrorCode; stdcall; begin try result := LSF_ERR_NONE; - if not CheckShaderFileHandle(aHandle) - then result := LastErrorCode - else TShaderFile(aHandle).LogCallback := aCallback; + if CheckShaderFileHandle(aHandle) then with TShaderFile(aHandle) do begin + LogCallback := aCallback; + LogUserArgs := aUserArgs; + end else + result := LastErrorCode; except on e: Exception do begin SetLastError(e); @@ -205,6 +275,21 @@ begin end; end; +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_ShaderFile_getGeneratorNames(const aHandle: TlsfShaderFileHandle): PAnsiChar; stdcall; +begin + try + if not CheckShaderFileHandle(aHandle) + then result := nil + else result := PAnsiChar(TShaderFile(aHandle).GeneratorNames); + except + on e: Exception do begin + SetLastError(e); + result := nil; + end; + end; +end; + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function lsf_ShaderFile_destroy(const aHandle: TlsfShaderFileHandle): TlsfErrorCode; stdcall; begin @@ -221,6 +306,135 @@ begin end; end; +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Generator///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_Generator_create(const aHandle: TlsfShaderFileHandle; const aName: PAnsiChar): TlsfShaderGeneratorHandle; stdcall; +begin + try + if not CheckShaderFileHandle(aHandle) + then result := nil + else result := TShaderFile(aHandle).CreateGenerator(string(aName)); + except + on e: Exception do begin + SetLastError(e); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_Generator_getPropertyNames(const aHandle: TlsfShaderGeneratorHandle): PAnsiChar; stdcall; +begin + try + if not CheckShaderGeneratorHandle(aHandle) + then result := nil + else result := PAnsiChar(TShaderGenerator(aHandle).PropertyNames); + except + on e: Exception do begin + SetLastError(e); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_Generator_getProperty(const aHandle: TlsfShaderGeneratorHandle; const aIndex: Integer): PAnsiChar; stdcall; +begin + try + if not CheckShaderGeneratorHandle(aHandle) + then result := nil + else result := TShaderGenerator(aHandle).GetProperty(aIndex); + except + on e: Exception do begin + SetLastError(e); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_Generator_getPropertyByName(const aHandle: TlsfShaderGeneratorHandle; const aName: PAnsiChar): PAnsiChar; stdcall; +begin + try + if not CheckShaderGeneratorHandle(aHandle) + then result := nil + else result := TShaderGenerator(aHandle).GetProperty(aName); + except + on e: Exception do begin + SetLastError(e); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_Generator_setProperty(const aHandle: TlsfShaderGeneratorHandle; const aIndex: Integer; const aValue: PAnsiChar): TlsfErrorCode; stdcall; +begin + try + if not CheckShaderGeneratorHandle(aHandle) + then result := LastErrorCode + else result := TShaderGenerator(aHandle).SetProperty(aIndex, aValue); + except + on e: Exception do begin + SetLastError(e); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_Generator_setPropertyByName(const aHandle: TlsfShaderGeneratorHandle; const aName, aValue: PAnsiChar): TlsfErrorCode; stdcall; +begin + try + if not CheckShaderGeneratorHandle(aHandle) + then result := LastErrorCode + else result := TShaderGenerator(aHandle).SetProperty(aName, aValue); + except + on e: Exception do begin + SetLastError(e); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_Generator_generateCode(const aHandle: TlsfShaderGeneratorHandle): PAnsiChar; stdcall; +begin + try + if not CheckShaderGeneratorHandle(aHandle) + then result := nil + else result := TShaderGenerator(aHandle).GenerateCode; + except + on e: Exception do begin + SetLastError(e); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_Generator_destroy(const aHandle: TlsfShaderGeneratorHandle): TlsfErrorCode; stdcall; +var + sg: TShaderGenerator; + sf: TShaderFile; +begin + try + result := LSF_ERR_NONE; + if CheckShaderGeneratorHandle(aHandle) then begin + sg := TShaderGenerator(aHandle); + sf := sg.Owner; + sf.DestroyGenerator(sg); + end else + result := LastErrorCode; + except + on e: Exception do begin + SetLastError(e); + result := LastErrorCode; + end; + end; +end; + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Global//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -228,7 +442,8 @@ function lsf_init: TlsfErrorCode; stdcall; begin try result := LSF_ERR_NONE; - ShaderFiles := TengShaderFiles.Create(true); + ShaderFiles := TShaderFileHashSet.Create(true); + ShaderGenerators := TShaderGeneratorHashSet.Create(false); except on e: Exception do begin SetLastError(e); @@ -260,6 +475,7 @@ function lsf_finish: TlsfErrorCode; stdcall; begin try result := LSF_ERR_NONE; + FreeAndNil(ShaderGenerators); FreeAndNil(ShaderFiles); except on e: Exception do begin @@ -274,14 +490,115 @@ exports lsf_ShaderFile_setLogCallback, lsf_ShaderFile_loadFromFile, lsf_ShaderFile_saveToFile, + lsf_ShaderFile_getGeneratorNames, lsf_ShaderFile_destroy, + lsf_Generator_create, + lsf_Generator_getPropertyNames, + lsf_Generator_getProperty, + lsf_Generator_getPropertyByName, + lsf_Generator_setProperty, + lsf_Generator_setPropertyByName, + lsf_Generator_generateCode, + lsf_Generator_destroy, + lsf_init, lsf_getLastErrorCode, lsf_getLastErrorMsg, lsf_getLastErrorTrace, lsf_finish; +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TShaderGenerator////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TShaderGenerator.GetProperty(const aIndex: Integer): PAnsiChar; +begin + result := nil; + if (aIndex < 0) or (aIndex >= fProperties.Count) then begin + SetLastError(LSF_ERR_INVALID_PROPERTY_INDEX, Format('index (%d) out of range (%d:%d)', [aIndex, 0, fProperties.Count-1])); + exit; + end; + fPropertyValue := fProperties.ValueAt[aIndex]; + result := PAnsiChar(fPropertyValue); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TShaderGenerator.GetProperty(const aName: String): PAnsiChar; +var + i: Integer; +begin + result := nil; + i := fProperties.IndexOf(aName); + if (i >= 0) + then result := GetProperty(i) + else SetLastError(LSF_ERR_INVALID_PROPERTY_NAME, Format('%s is not a valid/known property name', [aName])); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TShaderGenerator.SetProperty(const aIndex: Integer; const aValue: PAnsiChar): TlsfErrorCode; +begin + result := LSF_ERR_NONE; + if (aIndex < 0) or (aIndex >= fProperties.Count) then begin + SetLastError(LSF_ERR_INVALID_PROPERTY_INDEX, Format('index (%d) out of range (%d:%d)', [aIndex, 0, fProperties.Count-1])); + result := LastErrorCode; + end; + fProperties.ValueAt[aIndex] := string(aValue); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TShaderGenerator.SetProperty(const aName: String; const aValue: PAnsiChar): TlsfErrorCode; +var + i: Integer; +begin + i := fProperties.IndexOf(aName); + if (i <= 0) then begin + SetLastError(LSF_ERR_INVALID_PROPERTY_NAME, Format('%s is not a valid/known property name', [aName])); + result := LastErrorCode; + end else + result := SetProperty(i, aValue) +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TShaderGenerator.GenerateCode: PAnsiChar; +var + kvp: TPropertyMap.TKeyValuePair; + c: TengShaderCode; +begin + for kvp in fProperties.KeyValuePairs do + fGenerator.PropertyByName[kvp.Key] := kvp.Value; + c := TengShaderCode.Create; + try + fGenerator.GenerateCode(c); + fGeneratedCode := c.Text; + result := PAnsiChar(fGeneratedCode); + finally + FreeAndNil(c); + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TShaderGenerator.Create(const aOwner: TShaderFile; const aGenerator: TengShaderGenerator); +var + i: Integer; +begin + inherited Create; + fOwner := aOwner; + fGenerator := aGenerator; + fProperties := TPropertyMap.Create(true); + fPropertyNames := ''; + for i := 0 to fGenerator.PropertyCount-1 do begin + fProperties.Add(fGenerator.PropertyNames[i], fGenerator.PropertyByIndex[i]); + fPropertyNames := fPropertyNames + fGenerator.PropertyNames[i] + sLineBreak; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +destructor TShaderGenerator.Destroy; +begin + FreeAndNil(fProperties); + inherited Destroy; +end; + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TShaderFile/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -292,7 +609,65 @@ begin inherited LogMsgIntern(aSender, aLogLevel, aMsg); tmp := fLogCallback; if Assigned(tmp) then - tmp(Cardinal(aLogLevel), PAnsiChar(aMsg)); + tmp(Cardinal(aLogLevel), PAnsiChar(aMsg), fLogUserArgs); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TShaderFile.LoadFromFile(const aFilename: String); +var + i: Integer; +begin + inherited LoadFromFile(aFilename, nil); + fGeneratorNames := ''; + for i := 0 to GeneratorCount-1 do + fGeneratorNames := fGeneratorNames + inherited GeneratorNames[i] + sLineBreak; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TShaderFile.CreateGenerator(const aName: String): TShaderGenerator; + + function CheckName: Boolean; + var + i: Integer; + begin + result := true; + for i := 0 to GeneratorCount-1 do + if (inherited GeneratorNames[i] = aName) then + exit; + result := false; + end; + +begin + result := nil; + if not CheckName then begin + SetLastError(LSF_ERR_INVALID_GENERATOR_NAME, 'a generator with the name ''' + aName + ''' does not exist'); + exit; + end; + result := TShaderGenerator.Create(self, Generator[aName]); + fGenerators.Add(result); + ShaderGenerators.Add(result); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TShaderFile.DestroyGenerator(const aGenerator: TShaderGenerator); +begin + if Assigned(ShaderGenerators) then + ShaderGenerators.Remove(aGenerator); + fGenerators.Remove(aGenerator); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TShaderFile.Create; +begin + inherited Create; + fGenerators := TShaderGeneratorHashSet.Create(true); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +destructor TShaderFile.Destroy; +begin + FreeAndNil(fGenerators); + inherited Destroy; end; end.