* implementation of library almost finished * fixed some small compiler warningsmaster
| @@ -0,0 +1,78 @@ | |||
| #include <stdio.h> | |||
| #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; | |||
| } | |||
| @@ -0,0 +1,91 @@ | |||
| #include "libShaderFile.h" | |||
| //#define LSF_DEBUG | |||
| #ifdef LSF_DEBUG | |||
| # include <stdio.h> | |||
| #endif | |||
| #if defined(WIN32) || defined(WIN64) | |||
| # include <windows.h> | |||
| 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 <dlfcn.h> | |||
| # 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; | |||
| } | |||
| @@ -0,0 +1,88 @@ | |||
| #ifndef LIB_SHADER_FILE_H | |||
| #define LIB_SHADER_FILE_H | |||
| #include <stdint.h> | |||
| #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 */ | |||
| @@ -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. | |||
| @@ -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. | |||
| @@ -20,8 +20,127 @@ | |||
| <VersionInfo> | |||
| <StringTable ProductVersion=""/> | |||
| </VersionInfo> | |||
| <BuildModes Count="1"> | |||
| <Item1 Name="Default" Default="True"/> | |||
| <BuildModes Count="4"> | |||
| <Item1 Name="Win32Debug" Default="True"/> | |||
| <Item2 Name="Win32Release"> | |||
| <CompilerOptions> | |||
| <Version Value="11"/> | |||
| <PathDelim Value="\"/> | |||
| <Target> | |||
| <Filename Value="libShaderFile-$(TargetCPU)-$(TargetOS)"/> | |||
| </Target> | |||
| <SearchPaths> | |||
| <IncludeFiles Value="$(ProjOutDir)"/> | |||
| <OtherUnitFiles Value=".."/> | |||
| <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> | |||
| </SearchPaths> | |||
| <CodeGeneration> | |||
| <SmartLinkUnit Value="True"/> | |||
| <RelocatableUnit Value="True"/> | |||
| <TargetCPU Value="i386"/> | |||
| <TargetOS Value="win32"/> | |||
| <Optimizations> | |||
| <OptimizationLevel Value="3"/> | |||
| </Optimizations> | |||
| </CodeGeneration> | |||
| <Linking> | |||
| <Debugging> | |||
| <GenerateDebugInfo Value="False"/> | |||
| </Debugging> | |||
| <LinkSmart Value="True"/> | |||
| <Options> | |||
| <ExecutableType Value="Library"/> | |||
| </Options> | |||
| </Linking> | |||
| <Other> | |||
| <CompilerMessages> | |||
| <IgnoredMessages idx5024="True"/> | |||
| </CompilerMessages> | |||
| </Other> | |||
| </CompilerOptions> | |||
| </Item2> | |||
| <Item3 Name="Win64Debug"> | |||
| <CompilerOptions> | |||
| <Version Value="11"/> | |||
| <PathDelim Value="\"/> | |||
| <Target> | |||
| <Filename Value="libShaderFile-$(TargetCPU)-$(TargetOS)"/> | |||
| </Target> | |||
| <SearchPaths> | |||
| <IncludeFiles Value="$(ProjOutDir)"/> | |||
| <OtherUnitFiles Value=".."/> | |||
| <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> | |||
| </SearchPaths> | |||
| <Parsing> | |||
| <SyntaxOptions> | |||
| <IncludeAssertionCode Value="True"/> | |||
| </SyntaxOptions> | |||
| </Parsing> | |||
| <CodeGeneration> | |||
| <RelocatableUnit Value="True"/> | |||
| <Checks> | |||
| <IOChecks Value="True"/> | |||
| <RangeChecks Value="True"/> | |||
| <OverflowChecks Value="True"/> | |||
| <StackChecks Value="True"/> | |||
| </Checks> | |||
| <TargetCPU Value="x86_64"/> | |||
| <TargetOS Value="win64"/> | |||
| </CodeGeneration> | |||
| <Linking> | |||
| <Debugging> | |||
| <DebugInfoType Value="dsDwarf2Set"/> | |||
| <UseHeaptrc Value="True"/> | |||
| <UseExternalDbgSyms Value="True"/> | |||
| </Debugging> | |||
| <Options> | |||
| <ExecutableType Value="Library"/> | |||
| </Options> | |||
| </Linking> | |||
| <Other> | |||
| <CompilerMessages> | |||
| <IgnoredMessages idx5024="True"/> | |||
| </CompilerMessages> | |||
| </Other> | |||
| </CompilerOptions> | |||
| </Item3> | |||
| <Item4 Name="Win64Release"> | |||
| <CompilerOptions> | |||
| <Version Value="11"/> | |||
| <PathDelim Value="\"/> | |||
| <Target> | |||
| <Filename Value="libShaderFile-$(TargetCPU)-$(TargetOS)"/> | |||
| </Target> | |||
| <SearchPaths> | |||
| <IncludeFiles Value="$(ProjOutDir)"/> | |||
| <OtherUnitFiles Value=".."/> | |||
| <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> | |||
| </SearchPaths> | |||
| <CodeGeneration> | |||
| <SmartLinkUnit Value="True"/> | |||
| <RelocatableUnit Value="True"/> | |||
| <TargetCPU Value="x86_64"/> | |||
| <TargetOS Value="win64"/> | |||
| <Optimizations> | |||
| <OptimizationLevel Value="3"/> | |||
| </Optimizations> | |||
| </CodeGeneration> | |||
| <Linking> | |||
| <Debugging> | |||
| <GenerateDebugInfo Value="False"/> | |||
| </Debugging> | |||
| <LinkSmart Value="True"/> | |||
| <Options> | |||
| <ExecutableType Value="Library"/> | |||
| </Options> | |||
| </Linking> | |||
| <Other> | |||
| <CompilerMessages> | |||
| <IgnoredMessages idx5024="True"/> | |||
| </CompilerMessages> | |||
| </Other> | |||
| </CompilerOptions> | |||
| </Item4> | |||
| </BuildModes> | |||
| <PublishOptions> | |||
| <Version Value="2"/> | |||
| @@ -35,7 +154,6 @@ | |||
| <Unit0> | |||
| <Filename Value="libShaderFile.lpr"/> | |||
| <IsPartOfProject Value="True"/> | |||
| <UnitName Value="libShaderFile"/> | |||
| </Unit0> | |||
| </Units> | |||
| </ProjectOptions> | |||
| @@ -43,21 +161,44 @@ | |||
| <Version Value="11"/> | |||
| <PathDelim Value="\"/> | |||
| <Target> | |||
| <Filename Value="libShaderFile"/> | |||
| <Filename Value="libShaderFile-$(TargetCPU)-$(TargetOS)"/> | |||
| </Target> | |||
| <SearchPaths> | |||
| <IncludeFiles Value="$(ProjOutDir)"/> | |||
| <OtherUnitFiles Value=".."/> | |||
| <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> | |||
| </SearchPaths> | |||
| <Parsing> | |||
| <SyntaxOptions> | |||
| <IncludeAssertionCode Value="True"/> | |||
| </SyntaxOptions> | |||
| </Parsing> | |||
| <CodeGeneration> | |||
| <RelocatableUnit Value="True"/> | |||
| <Checks> | |||
| <IOChecks Value="True"/> | |||
| <RangeChecks Value="True"/> | |||
| <OverflowChecks Value="True"/> | |||
| <StackChecks Value="True"/> | |||
| </Checks> | |||
| <TargetCPU Value="i386"/> | |||
| <TargetOS Value="win32"/> | |||
| </CodeGeneration> | |||
| <Linking> | |||
| <Debugging> | |||
| <DebugInfoType Value="dsDwarf2Set"/> | |||
| <UseHeaptrc Value="True"/> | |||
| <UseExternalDbgSyms Value="True"/> | |||
| </Debugging> | |||
| <Options> | |||
| <ExecutableType Value="Library"/> | |||
| </Options> | |||
| </Linking> | |||
| <Other> | |||
| <CompilerMessages> | |||
| <IgnoredMessages idx5024="True"/> | |||
| </CompilerMessages> | |||
| </Other> | |||
| </CompilerOptions> | |||
| <Debugging> | |||
| <Exceptions Count="3"> | |||
| @@ -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<string, variant>; | |||
| 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<TlsfShaderGeneratorHandle>; | |||
| 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<TShaderFile>; | |||
| TShaderFileHashSet = specialize TutlHashSet<TShaderFile>; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| 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. | |||
| @@ -85,8 +85,8 @@ end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TengShaderFile.GetGeneratorNames(const aIndex: Integer): String; | |||
| begin | |||
| if (aIndex < 0) or (aIndex >= Count) then | |||
| raise EengOutOfRange.Create(0, Count-1, aIndex, self); | |||
| if (aIndex < 0) or (aIndex >= GeneratorCount) then | |||
| raise EengOutOfRange.Create(0, GeneratorCount-1, aIndex, self); | |||
| if (aIndex = 0) | |||
| then result := '' | |||
| else result := fClasses.Keys[aIndex-1]; | |||
| @@ -430,6 +430,8 @@ begin | |||
| case aIndex of | |||
| 0: result := fFirst; | |||
| 1: result := fSecond; | |||
| else | |||
| result := nil; | |||
| end; | |||
| end; | |||
| @@ -858,7 +858,9 @@ begin | |||
| else if (cmp < 0) then | |||
| result := SearchItem(aMin, i-1, aItem, aIndex) | |||
| else if (cmp > 0) then | |||
| result := SearchItem(i+1, aMax, aItem, aIndex); | |||
| result := SearchItem(i+1, aMax, aItem, aIndex) | |||
| else | |||
| result := -1; | |||
| end else begin | |||
| result := -1; | |||
| aIndex := aMin; | |||
| @@ -673,7 +673,8 @@ var | |||
| i, len: Integer; | |||
| s: String; | |||
| begin | |||
| csi := fCode.Last; | |||
| csi := fCode.Last; | |||
| result := 0; | |||
| if not Assigned(aCommand) then | |||
| exit; | |||
| @@ -161,6 +161,7 @@ end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TengShaderPart.{%H-}GetChild(const aIndex: Integer): TengShaderPart; | |||
| begin | |||
| result := nil; | |||
| EengShaderPartInternal.Create('this part does not have any children'); | |||
| end; | |||
| @@ -40,11 +40,7 @@ implementation | |||
| uses | |||
| uengShaderPartKeyValuePair, uengShaderPartClass, uengShaderPartMessage, uengShaderPartMeta, | |||
| uengShaderPartCall, uengShaderPartProc, uengShaderPartText, uengShaderPartEcho, uengShaderPartIf, | |||
| uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment, uengShaderFileConstants | |||
| {$IFDEF SHADER_FILE_DEBUG} | |||
| , uengShaderFileTypes | |||
| {$ENDIF} | |||
| ; | |||
| uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment, uengShaderFileConstants; | |||
| const | |||
| TOKEN_CLASSES: array[0..22] of CengShaderCodePart = ( | |||
| @@ -129,6 +129,8 @@ begin | |||
| case aIndex of | |||
| 0: result := fIfPart; | |||
| 1: result := fElsePart; | |||
| else | |||
| result := nil; | |||
| end; | |||
| end; | |||
| @@ -251,7 +251,7 @@ begin | |||
| ((gfGenerateInlineCode in aArgs.Flags) or fIsInline) then | |||
| begin | |||
| GenerateInlineCode(aArgs); | |||
| if (GetTokenName = TOKEN_PROC) then | |||
| if not (self is TengShaderPartFunc) then | |||
| aArgs.IgnoreNextCommandEnd; | |||
| // generate code | |||