mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
libobs: Add HLSL annotation parsing
Gives the ability to retrieve param annotations. Blocks wrapped in <> following a parameter. For example: float slider < float max_value = 10.0; float min_value = 0.0; >; These blocks are not for shading purposes but to help describe the shader's gui as in the example above. Adds graphics api functions for retrieving annotations: size_t gs_param_get_num_annotations(const gs_eparam_t *param); gs_eparam_t *gs_param_get_annotation_by_idx(const gs_eparam_t *param, size_t annotation); gs_eparam_t *gs_param_get_annotation_by_name(const gs_eparam_t *param, const char *name);
This commit is contained in:
parent
a8517f3698
commit
af67086912
@ -137,8 +137,11 @@ void gs_shader::BuildConstantBuffer()
|
||||
case GS_SHADER_PARAM_BOOL:
|
||||
case GS_SHADER_PARAM_INT:
|
||||
case GS_SHADER_PARAM_FLOAT: size = sizeof(float); break;
|
||||
case GS_SHADER_PARAM_INT2:
|
||||
case GS_SHADER_PARAM_VEC2: size = sizeof(vec2); break;
|
||||
case GS_SHADER_PARAM_INT3:
|
||||
case GS_SHADER_PARAM_VEC3: size = sizeof(float)*3; break;
|
||||
case GS_SHADER_PARAM_INT4:
|
||||
case GS_SHADER_PARAM_VEC4: size = sizeof(vec4); break;
|
||||
case GS_SHADER_PARAM_MATRIX4X4:
|
||||
size = sizeof(float)*4*4;
|
||||
|
@ -21,6 +21,39 @@
|
||||
#include "effect-parser.h"
|
||||
#include "effect.h"
|
||||
|
||||
static inline bool ep_parse_param_assign(struct effect_parser *ep,
|
||||
struct ep_param *param);
|
||||
|
||||
static enum gs_shader_param_type get_effect_param_type(const char *type)
|
||||
{
|
||||
if (strcmp(type, "float") == 0)
|
||||
return GS_SHADER_PARAM_FLOAT;
|
||||
else if (strcmp(type, "float2") == 0)
|
||||
return GS_SHADER_PARAM_VEC2;
|
||||
else if (strcmp(type, "float3") == 0)
|
||||
return GS_SHADER_PARAM_VEC3;
|
||||
else if (strcmp(type, "float4") == 0)
|
||||
return GS_SHADER_PARAM_VEC4;
|
||||
else if (strcmp(type, "int2") == 0)
|
||||
return GS_SHADER_PARAM_INT2;
|
||||
else if (strcmp(type, "int3") == 0)
|
||||
return GS_SHADER_PARAM_INT3;
|
||||
else if (strcmp(type, "int4") == 0)
|
||||
return GS_SHADER_PARAM_INT4;
|
||||
else if (astrcmp_n(type, "texture", 7) == 0)
|
||||
return GS_SHADER_PARAM_TEXTURE;
|
||||
else if (strcmp(type, "float4x4") == 0)
|
||||
return GS_SHADER_PARAM_MATRIX4X4;
|
||||
else if (strcmp(type, "bool") == 0)
|
||||
return GS_SHADER_PARAM_BOOL;
|
||||
else if (strcmp(type, "int") == 0)
|
||||
return GS_SHADER_PARAM_INT;
|
||||
else if (strcmp(type, "string") == 0)
|
||||
return GS_SHADER_PARAM_STRING;
|
||||
|
||||
return GS_SHADER_PARAM_UNKNOWN;
|
||||
}
|
||||
|
||||
void ep_free(struct effect_parser *ep)
|
||||
{
|
||||
size_t i;
|
||||
@ -92,6 +125,18 @@ static inline struct ep_param *ep_getparam(struct effect_parser *ep,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct ep_param *ep_getannotation(struct ep_param *param,
|
||||
const char *name)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < param->annotations.num; i++) {
|
||||
if (strcmp(name, param->annotations.array[i].name) == 0)
|
||||
return param->annotations.array+i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct ep_func *ep_getfunc_strref(struct effect_parser *ep,
|
||||
const struct strref *ref)
|
||||
{
|
||||
@ -262,6 +307,145 @@ error:
|
||||
ep_struct_free(&eps);
|
||||
}
|
||||
|
||||
static inline int ep_parse_param_annotation_var(struct effect_parser *ep,
|
||||
struct ep_param *var)
|
||||
{
|
||||
int code;
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* variable type */
|
||||
|
||||
if (!cf_next_valid_token(&ep->cfp))
|
||||
return PARSE_EOF;
|
||||
|
||||
if (cf_token_is(&ep->cfp, ";"))
|
||||
return PARSE_CONTINUE;
|
||||
if (cf_token_is(&ep->cfp, ">"))
|
||||
return PARSE_BREAK;
|
||||
|
||||
code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "type name", ";");
|
||||
if (code != PARSE_SUCCESS)
|
||||
return code;
|
||||
|
||||
bfree(var->type);
|
||||
cf_copy_token(&ep->cfp, &var->type);
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* variable name */
|
||||
|
||||
if (!cf_next_valid_token(&ep->cfp))
|
||||
return PARSE_EOF;
|
||||
|
||||
if (cf_token_is(&ep->cfp, ";")) {
|
||||
cf_adderror_expecting(&ep->cfp, "variable name");
|
||||
return PARSE_UNEXPECTED_CONTINUE;
|
||||
}
|
||||
if (cf_token_is(&ep->cfp, ">")) {
|
||||
cf_adderror_expecting(&ep->cfp, "variable name");
|
||||
return PARSE_UNEXPECTED_BREAK;
|
||||
}
|
||||
|
||||
code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "variable name", ";");
|
||||
if (code != PARSE_SUCCESS)
|
||||
return code;
|
||||
|
||||
bfree(var->name);
|
||||
cf_copy_token(&ep->cfp, &var->name);
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* variable mapping if any (POSITION, TEXCOORD, etc) */
|
||||
|
||||
if (!cf_next_valid_token(&ep->cfp))
|
||||
return PARSE_EOF;
|
||||
|
||||
if (cf_token_is(&ep->cfp, ":")) {
|
||||
cf_adderror_expecting(&ep->cfp, "= or ;");
|
||||
return PARSE_UNEXPECTED_BREAK;
|
||||
} else if (cf_token_is(&ep->cfp, ">")) {
|
||||
cf_adderror_expecting(&ep->cfp, "= or ;");
|
||||
return PARSE_UNEXPECTED_BREAK;
|
||||
} else if (cf_token_is(&ep->cfp, "=")) {
|
||||
if (!ep_parse_param_assign(ep, var)) {
|
||||
cf_adderror_expecting(&ep->cfp, "assignment value");
|
||||
return PARSE_UNEXPECTED_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
|
||||
if (!cf_token_is(&ep->cfp, ";")) {
|
||||
if (!cf_go_to_valid_token(&ep->cfp, ";", ">")) {
|
||||
cf_adderror_expecting(&ep->cfp, "; or >");
|
||||
return PARSE_EOF;
|
||||
}
|
||||
return PARSE_CONTINUE;
|
||||
}
|
||||
|
||||
return PARSE_SUCCESS;
|
||||
}
|
||||
|
||||
static int ep_parse_annotations(struct effect_parser *ep,
|
||||
struct darray *annotations)
|
||||
{
|
||||
if (!cf_token_is(&ep->cfp, "<")) {
|
||||
cf_adderror_expecting(&ep->cfp, "<");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* get annotation variables */
|
||||
while (true) {
|
||||
bool do_break = false;
|
||||
struct ep_param var;
|
||||
|
||||
ep_param_init(&var, bstrdup(""), bstrdup(""), false, false,
|
||||
false);
|
||||
|
||||
switch (ep_parse_param_annotation_var(ep, &var)) {
|
||||
case PARSE_UNEXPECTED_CONTINUE:
|
||||
cf_adderror_syntax_error(&ep->cfp);
|
||||
/* Falls through. */
|
||||
case PARSE_CONTINUE:
|
||||
ep_param_free(&var);
|
||||
continue;
|
||||
|
||||
case PARSE_UNEXPECTED_BREAK:
|
||||
cf_adderror_syntax_error(&ep->cfp);
|
||||
/* Falls through. */
|
||||
case PARSE_BREAK:
|
||||
ep_param_free(&var);
|
||||
do_break = true;
|
||||
break;
|
||||
|
||||
case PARSE_EOF:
|
||||
ep_param_free(&var);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (do_break)
|
||||
break;
|
||||
|
||||
darray_push_back(sizeof(struct ep_param), annotations, &var);
|
||||
}
|
||||
|
||||
if (!cf_token_is(&ep->cfp, ">")) {
|
||||
cf_adderror_expecting(&ep->cfp, ">");
|
||||
goto error;
|
||||
}
|
||||
if (!cf_next_valid_token(&ep->cfp))
|
||||
goto error;
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ep_parse_param_annotations(struct effect_parser *ep,
|
||||
struct ep_param *param)
|
||||
{
|
||||
return ep_parse_annotations(ep, ¶m->annotations.da);
|
||||
}
|
||||
|
||||
static inline int ep_parse_pass_command_call(struct effect_parser *ep,
|
||||
struct darray *call)
|
||||
{
|
||||
@ -328,7 +512,7 @@ static int ep_parse_pass(struct effect_parser *ep, struct ep_pass *pass)
|
||||
|
||||
if (!cf_token_is(&ep->cfp, "{")) {
|
||||
pass->name = bstrdup_n(ep->cfp.cur_token->str.array,
|
||||
ep->cfp.cur_token->str.len);
|
||||
ep->cfp.cur_token->str.len);
|
||||
if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF;
|
||||
}
|
||||
|
||||
@ -356,9 +540,19 @@ static void ep_parse_technique(struct effect_parser *ep)
|
||||
|
||||
if (cf_next_name(&ep->cfp, &ept.name, "name", ";") != PARSE_SUCCESS)
|
||||
goto error;
|
||||
if (cf_next_token_should_be(&ep->cfp, "{", ";", NULL) != PARSE_SUCCESS)
|
||||
goto error;
|
||||
|
||||
if (!cf_next_valid_token(&ep->cfp))
|
||||
return;
|
||||
|
||||
if (!cf_token_is(&ep->cfp, "{")) {
|
||||
if (!cf_go_to_token(&ep->cfp, ";", NULL)) {
|
||||
cf_adderror_expecting(&ep->cfp, ";");
|
||||
return;
|
||||
}
|
||||
|
||||
cf_adderror_expecting(&ep->cfp, "{");
|
||||
goto error;
|
||||
}
|
||||
if (!cf_next_valid_token(&ep->cfp))
|
||||
goto error;
|
||||
|
||||
@ -756,6 +950,30 @@ static inline int ep_parse_param_assign_texture(struct effect_parser *ep,
|
||||
return PARSE_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int ep_parse_param_assign_string(struct effect_parser *ep,
|
||||
struct ep_param *param)
|
||||
{
|
||||
int code;
|
||||
char *str = NULL;
|
||||
|
||||
if (!cf_next_valid_token(&ep->cfp))
|
||||
return PARSE_EOF;
|
||||
|
||||
code = cf_token_is_type(&ep->cfp, CFTOKEN_STRING, "string", ";");
|
||||
if (code != PARSE_SUCCESS)
|
||||
return code;
|
||||
|
||||
str = cf_literal_to_str(ep->cfp.cur_token->str.array,
|
||||
ep->cfp.cur_token->str.len);
|
||||
|
||||
if (str) {
|
||||
da_copy_array(param->default_val, str, strlen(str) + 1);
|
||||
bfree(str);
|
||||
}
|
||||
|
||||
return PARSE_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int ep_parse_param_assign_intfloat(struct effect_parser *ep,
|
||||
struct ep_param *param, bool is_float)
|
||||
{
|
||||
@ -789,30 +1007,51 @@ static inline int ep_parse_param_assign_intfloat(struct effect_parser *ep,
|
||||
return PARSE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* parses assignment for float1, float2, float3, float4, and any combination
|
||||
* for float3x3, float4x4, etc
|
||||
*/
|
||||
static inline int ep_parse_param_assign_float_array(struct effect_parser *ep,
|
||||
static inline int ep_parse_param_assign_bool(struct effect_parser *ep,
|
||||
struct ep_param *param)
|
||||
{
|
||||
const char *float_type = param->type+5;
|
||||
int float_count = 0, code, i;
|
||||
if (!cf_next_valid_token(&ep->cfp))
|
||||
return PARSE_EOF;
|
||||
|
||||
if (cf_token_is(&ep->cfp, "true")) {
|
||||
long l = 1;
|
||||
da_push_back_array(param->default_val, &l, sizeof(long));
|
||||
return PARSE_SUCCESS;
|
||||
} else if (cf_token_is(&ep->cfp, "false")) {
|
||||
long l = 0;
|
||||
da_push_back_array(param->default_val, &l, sizeof(long));
|
||||
return PARSE_SUCCESS;
|
||||
}
|
||||
|
||||
cf_adderror_expecting(&ep->cfp, "true or false");
|
||||
|
||||
return PARSE_EOF;
|
||||
}
|
||||
|
||||
/*
|
||||
* parses assignment for float1, float2, float3, float4, int1, int2, int3, int4,
|
||||
* and any combination for float3x3, float4x4, int3x3, int4x4, etc
|
||||
*/
|
||||
static inline int ep_parse_param_assign_intfloat_array(struct effect_parser *ep,
|
||||
struct ep_param *param, bool is_float)
|
||||
{
|
||||
const char *intfloat_type = param->type + (is_float ? 5 : 3);
|
||||
int intfloat_count = 0, code, i;
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
if (float_type[0] < '1' || float_type[0] > '4')
|
||||
if (intfloat_type[0] < '1' || intfloat_type[0] > '4')
|
||||
cf_adderror(&ep->cfp, "Invalid row count", LEX_ERROR,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
float_count = float_type[0]-'0';
|
||||
intfloat_count = intfloat_type[0]-'0';
|
||||
|
||||
if (float_type[1] == 'x') {
|
||||
if (float_type[2] < '1' || float_type[2] > '4')
|
||||
if (intfloat_type[1] == 'x') {
|
||||
if (intfloat_type[2] < '1' || intfloat_type[2] > '4')
|
||||
cf_adderror(&ep->cfp, "Invalid column count",
|
||||
LEX_ERROR, NULL, NULL, NULL);
|
||||
|
||||
float_count *= float_type[2]-'0';
|
||||
intfloat_count *= intfloat_type[2]-'0';
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -820,10 +1059,10 @@ static inline int ep_parse_param_assign_float_array(struct effect_parser *ep,
|
||||
code = cf_next_token_should_be(&ep->cfp, "{", ";", NULL);
|
||||
if (code != PARSE_SUCCESS) return code;
|
||||
|
||||
for (i = 0; i < float_count; i++) {
|
||||
char *next = ((i+1) < float_count) ? "," : "}";
|
||||
for (i = 0; i < intfloat_count; i++) {
|
||||
char *next = ((i+1) < intfloat_count) ? "," : "}";
|
||||
|
||||
code = ep_parse_param_assign_intfloat(ep, param, true);
|
||||
code = ep_parse_param_assign_intfloat(ep, param, is_float);
|
||||
if (code != PARSE_SUCCESS) return code;
|
||||
|
||||
code = cf_next_token_should_be(&ep->cfp, next, ";", NULL);
|
||||
@ -842,8 +1081,14 @@ static int ep_parse_param_assignment_val(struct effect_parser *ep,
|
||||
return ep_parse_param_assign_intfloat(ep, param, false);
|
||||
else if (strcmp(param->type, "float") == 0)
|
||||
return ep_parse_param_assign_intfloat(ep, param, true);
|
||||
else if (astrcmp_n(param->type, "int", 3) == 0)
|
||||
return ep_parse_param_assign_intfloat_array(ep, param, false);
|
||||
else if (astrcmp_n(param->type, "float", 5) == 0)
|
||||
return ep_parse_param_assign_float_array(ep, param);
|
||||
return ep_parse_param_assign_intfloat_array(ep, param, true);
|
||||
else if (astrcmp_n(param->type, "string", 6) == 0)
|
||||
return ep_parse_param_assign_string(ep, param);
|
||||
else if (strcmp(param->type, "bool") == 0)
|
||||
return ep_parse_param_assign_bool(ep, param);
|
||||
|
||||
cf_adderror(&ep->cfp, "Invalid type '$1' used for assignment",
|
||||
LEX_ERROR, param->type, NULL, NULL);
|
||||
@ -879,6 +1124,9 @@ static void ep_parse_param(struct effect_parser *ep,
|
||||
goto complete;
|
||||
if (cf_token_is(&ep->cfp, "[") && !ep_parse_param_array(ep, ¶m))
|
||||
goto error;
|
||||
if (cf_token_is(&ep->cfp, "<") && !ep_parse_param_annotations(ep,
|
||||
¶m))
|
||||
goto error;
|
||||
if (cf_token_is(&ep->cfp, "=") && !ep_parse_param_assign(ep, ¶m))
|
||||
goto error;
|
||||
/*
|
||||
@ -945,7 +1193,6 @@ static void ep_parse_other(struct effect_parser *ep)
|
||||
goto error;
|
||||
if (cf_next_name(&ep->cfp, &name, "name", ";") != PARSE_SUCCESS)
|
||||
goto error;
|
||||
|
||||
if (!cf_next_valid_token(&ep->cfp))
|
||||
goto error;
|
||||
|
||||
@ -1339,6 +1586,35 @@ static void ep_makeshaderstring(struct effect_parser *ep,
|
||||
ep_reset_written(ep);
|
||||
}
|
||||
|
||||
static void ep_compile_annotations(struct darray *ep_annotations,
|
||||
struct darray *gsp_annotations, struct effect_parser *ep)
|
||||
{
|
||||
darray_resize(sizeof(struct gs_effect_param),
|
||||
gsp_annotations, ep_annotations->num);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < ep_annotations->num; i++) {
|
||||
struct gs_effect_param *param = ((struct gs_effect_param *)
|
||||
gsp_annotations->array)+i;
|
||||
struct ep_param *param_in = ((struct ep_param *)
|
||||
ep_annotations->array)+i;
|
||||
|
||||
param->name = bstrdup(param_in->name);
|
||||
param->section = EFFECT_ANNOTATION;
|
||||
param->effect = ep->effect;
|
||||
da_move(param->default_val, param_in->default_val);
|
||||
|
||||
param->type = get_effect_param_type(param_in->type);
|
||||
}
|
||||
}
|
||||
|
||||
static void ep_compile_param_annotations(struct ep_param *ep_param_input,
|
||||
struct gs_effect_param *gs_effect_input, struct effect_parser *ep)
|
||||
{
|
||||
ep_compile_annotations(&(ep_param_input->annotations.da),
|
||||
&(gs_effect_input->annotations.da), ep);
|
||||
}
|
||||
|
||||
static void ep_compile_param(struct effect_parser *ep, size_t idx)
|
||||
{
|
||||
struct gs_effect_param *param;
|
||||
@ -1353,27 +1629,14 @@ static void ep_compile_param(struct effect_parser *ep, size_t idx)
|
||||
param->effect = ep->effect;
|
||||
da_move(param->default_val, param_in->default_val);
|
||||
|
||||
if (strcmp(param_in->type, "bool") == 0)
|
||||
param->type = GS_SHADER_PARAM_BOOL;
|
||||
else if (strcmp(param_in->type, "float") == 0)
|
||||
param->type = GS_SHADER_PARAM_FLOAT;
|
||||
else if (strcmp(param_in->type, "int") == 0)
|
||||
param->type = GS_SHADER_PARAM_INT;
|
||||
else if (strcmp(param_in->type, "float2") == 0)
|
||||
param->type = GS_SHADER_PARAM_VEC2;
|
||||
else if (strcmp(param_in->type, "float3") == 0)
|
||||
param->type = GS_SHADER_PARAM_VEC3;
|
||||
else if (strcmp(param_in->type, "float4") == 0)
|
||||
param->type = GS_SHADER_PARAM_VEC4;
|
||||
else if (strcmp(param_in->type, "float4x4") == 0)
|
||||
param->type = GS_SHADER_PARAM_MATRIX4X4;
|
||||
else if (param_in->is_texture)
|
||||
param->type = GS_SHADER_PARAM_TEXTURE;
|
||||
param->type = get_effect_param_type(param_in->type);
|
||||
|
||||
if (strcmp(param_in->name, "ViewProj") == 0)
|
||||
ep->effect->view_proj = param;
|
||||
else if (strcmp(param_in->name, "World") == 0)
|
||||
ep->effect->world = param;
|
||||
|
||||
ep_compile_param_annotations(param_in, param, ep);
|
||||
}
|
||||
|
||||
static bool ep_compile_pass_shaderparams(struct effect_parser *ep,
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "../util/darray.h"
|
||||
#include "../util/cf-parser.h"
|
||||
#include "graphics.h"
|
||||
#include "shader-parser.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -72,6 +73,7 @@ struct ep_param {
|
||||
struct gs_effect_param *param;
|
||||
bool is_const, is_property, is_uniform, is_texture, written;
|
||||
int writeorder, array_count;
|
||||
DARRAY(struct ep_param) annotations;
|
||||
};
|
||||
|
||||
extern void ep_param_writevar(struct dstr *dst, struct darray *use_params);
|
||||
@ -91,6 +93,7 @@ static inline void ep_param_init(struct ep_param *epp,
|
||||
epp->array_count = 0;
|
||||
da_init(epp->default_val);
|
||||
da_init(epp->properties);
|
||||
da_init(epp->annotations);
|
||||
}
|
||||
|
||||
static inline void ep_param_free(struct ep_param *epp)
|
||||
@ -99,6 +102,10 @@ static inline void ep_param_free(struct ep_param *epp)
|
||||
bfree(epp->name);
|
||||
da_free(epp->default_val);
|
||||
da_free(epp->properties);
|
||||
|
||||
for (size_t i = 0; i < epp->annotations.num; i++)
|
||||
ep_param_free(epp->annotations.array + i);
|
||||
da_free(epp->annotations);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -286,6 +286,63 @@ gs_eparam_t *gs_effect_get_param_by_name(const gs_effect_t *effect,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t gs_param_get_num_annotations(const gs_eparam_t *param)
|
||||
{
|
||||
return param ? param->annotations.num : 0;
|
||||
}
|
||||
|
||||
gs_eparam_t *gs_param_get_annotation_by_idx(const gs_eparam_t *param,
|
||||
size_t annotation)
|
||||
{
|
||||
if (!param) return NULL;
|
||||
|
||||
struct gs_effect_param *params = param->annotations.array;
|
||||
if (annotation > param->annotations.num)
|
||||
return NULL;
|
||||
|
||||
return params + annotation;
|
||||
}
|
||||
|
||||
gs_eparam_t *gs_param_get_annotation_by_name(const gs_eparam_t *param,
|
||||
const char *name)
|
||||
{
|
||||
if (!param) return NULL;
|
||||
struct gs_effect_param *params = param->annotations.array;
|
||||
|
||||
for (size_t i = 0; i < param->annotations.num; i++) {
|
||||
struct gs_effect_param *g_param = params + i;
|
||||
if (strcmp(g_param->name, name) == 0)
|
||||
return g_param;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gs_epass_t *gs_technique_get_pass_by_idx(const gs_technique_t *technique,
|
||||
size_t pass)
|
||||
{
|
||||
if (!technique) return NULL;
|
||||
struct gs_effect_pass *passes = technique->passes.array;
|
||||
|
||||
if (pass > technique->passes.num)
|
||||
return NULL;
|
||||
|
||||
return passes + pass;
|
||||
}
|
||||
|
||||
gs_epass_t *gs_technique_get_pass_by_name(const gs_technique_t *technique,
|
||||
const char *name)
|
||||
{
|
||||
if (!technique) return NULL;
|
||||
struct gs_effect_pass *passes = technique->passes.array;
|
||||
|
||||
for (size_t i = 0; i < technique->passes.num; i++) {
|
||||
struct gs_effect_pass *g_pass = passes + i;
|
||||
if (strcmp(g_pass->name, name) == 0)
|
||||
return g_pass;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gs_eparam_t *gs_effect_get_viewproj_matrix(const gs_effect_t *effect)
|
||||
{
|
||||
return effect ? effect->view_proj : NULL;
|
||||
|
@ -41,7 +41,8 @@ enum effect_section {
|
||||
EFFECT_PARAM,
|
||||
EFFECT_TECHNIQUE,
|
||||
EFFECT_SAMPLER,
|
||||
EFFECT_PASS
|
||||
EFFECT_PASS,
|
||||
EFFECT_ANNOTATION
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -61,11 +62,13 @@ struct gs_effect_param {
|
||||
|
||||
/*char *full_name;
|
||||
float scroller_min, scroller_max, scroller_inc, scroller_mul;*/
|
||||
DARRAY(struct gs_effect_param) annotations;
|
||||
};
|
||||
|
||||
static inline void effect_param_init(struct gs_effect_param *param)
|
||||
{
|
||||
memset(param, 0, sizeof(struct gs_effect_param));
|
||||
da_init(param->annotations);
|
||||
}
|
||||
|
||||
static inline void effect_param_free(struct gs_effect_param *param)
|
||||
@ -74,6 +77,12 @@ static inline void effect_param_free(struct gs_effect_param *param)
|
||||
//bfree(param->full_name);
|
||||
da_free(param->cur_val);
|
||||
da_free(param->default_val);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < param->annotations.num; i++)
|
||||
effect_param_free(param->annotations.array + i);
|
||||
|
||||
da_free(param->annotations);
|
||||
}
|
||||
|
||||
EXPORT void effect_param_parse_property(gs_eparam_t *param,
|
||||
@ -106,6 +115,7 @@ static inline void effect_pass_free(struct gs_effect_pass *pass)
|
||||
bfree(pass->name);
|
||||
da_free(pass->vertshader_params);
|
||||
da_free(pass->pixelshader_params);
|
||||
|
||||
gs_shader_destroy(pass->vertshader);
|
||||
gs_shader_destroy(pass->pixelshader);
|
||||
}
|
||||
@ -130,6 +140,7 @@ static inline void effect_technique_free(struct gs_effect_technique *t)
|
||||
size_t i;
|
||||
for (i = 0; i < t->passes.num; i++)
|
||||
effect_pass_free(t->passes.array+i);
|
||||
|
||||
da_free(t->passes);
|
||||
bfree(t->name);
|
||||
}
|
||||
|
@ -267,6 +267,7 @@ typedef struct gs_shader gs_shader_t;
|
||||
typedef struct gs_shader_param gs_sparam_t;
|
||||
typedef struct gs_effect gs_effect_t;
|
||||
typedef struct gs_effect_technique gs_technique_t;
|
||||
typedef struct gs_effect_pass gs_epass_t;
|
||||
typedef struct gs_effect_param gs_eparam_t;
|
||||
typedef struct gs_device gs_device_t;
|
||||
typedef struct graphics_subsystem graphics_t;
|
||||
@ -368,12 +369,21 @@ EXPORT bool gs_technique_begin_pass(gs_technique_t *technique, size_t pass);
|
||||
EXPORT bool gs_technique_begin_pass_by_name(gs_technique_t *technique,
|
||||
const char *name);
|
||||
EXPORT void gs_technique_end_pass(gs_technique_t *technique);
|
||||
EXPORT gs_epass_t *gs_technique_get_pass_by_idx(const gs_technique_t *technique,
|
||||
size_t pass);
|
||||
EXPORT gs_epass_t *gs_technique_get_pass_by_name(
|
||||
const gs_technique_t *technique, const char *name);
|
||||
|
||||
EXPORT size_t gs_effect_get_num_params(const gs_effect_t *effect);
|
||||
EXPORT gs_eparam_t *gs_effect_get_param_by_idx(const gs_effect_t *effect,
|
||||
size_t param);
|
||||
EXPORT gs_eparam_t *gs_effect_get_param_by_name(const gs_effect_t *effect,
|
||||
const char *name);
|
||||
EXPORT size_t gs_param_get_num_annotations(const gs_eparam_t *param);
|
||||
EXPORT gs_eparam_t *gs_param_get_annotation_by_idx(const gs_eparam_t *param,
|
||||
size_t annotation);
|
||||
EXPORT gs_eparam_t *gs_param_get_annotation_by_name(const gs_eparam_t *param,
|
||||
const char *name);
|
||||
|
||||
/** Helper function to simplify effect usage. Use with a while loop that
|
||||
* contains drawing functions. Automatically handles techniques, passes, and
|
||||
|
Loading…
Reference in New Issue
Block a user