Browse Source

* implemented header file and simple example for c

* implementation of library almost finished
* fixed some small compiler warnings
master
Bergmann89 8 years ago
parent
commit
f366f88a8b
7 changed files with 953 additions and 151 deletions
  1. +78
    -0
      header/c/example/test.c
  2. +91
    -0
      header/c/libShaderFile.c
  3. +88
    -0
      header/c/libShaderFile.h
  4. +155
    -0
      header/delphi/ulibShaderFile.pas
  5. +0
    -126
      header/ulibShaderFile.pas
  6. +145
    -4
      libShaderFile.lpi
  7. +396
    -21
      libShaderFile.lpr

+ 78
- 0
header/c/example/test.c View File

@@ -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;
}

+ 91
- 0
header/c/libShaderFile.c View File

@@ -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;
}

+ 88
- 0
header/c/libShaderFile.h View File

@@ -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 */

+ 155
- 0
header/delphi/ulibShaderFile.pas View File

@@ -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.


+ 0
- 126
header/ulibShaderFile.pas View File

@@ -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.


+ 145
- 4
libShaderFile.lpi View File

@@ -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">


+ 396
- 21
libShaderFile.lpr View File

@@ -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.

Loading…
Cancel
Save