Add basic CPP struct reflection
This commit is contained in:
parent
28a1fe8b24
commit
2cd7acaacb
@ -4,6 +4,22 @@
|
|||||||
#define DQN_REFLECT
|
#define DQN_REFLECT
|
||||||
#define DQN_REFLECT_META(...)
|
#define DQN_REFLECT_META(...)
|
||||||
|
|
||||||
|
struct DqnReflect_StructMember
|
||||||
|
{
|
||||||
|
char const *type;
|
||||||
|
int type_len;
|
||||||
|
char const *name;
|
||||||
|
int name_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DqnReflect_Struct
|
||||||
|
{
|
||||||
|
char const *name;
|
||||||
|
int name_len;
|
||||||
|
DqnReflect_StructMember *members;
|
||||||
|
int members_len;
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// HOW TO REFLECT ANNOTATED CODE
|
// HOW TO REFLECT ANNOTATED CODE
|
||||||
// Define in the preprocessor, DQN_REFLECT_IMPLEMENTATION and compile
|
// Define in the preprocessor, DQN_REFLECT_IMPLEMENTATION and compile
|
||||||
@ -313,6 +329,7 @@ b32 StrCmp(StringLiteral a, StringLiteral b)
|
|||||||
X(SemiColon, ";") \
|
X(SemiColon, ";") \
|
||||||
X(Identifier, "Identifier") \
|
X(Identifier, "Identifier") \
|
||||||
X(Number, "[0-9]") \
|
X(Number, "[0-9]") \
|
||||||
|
X(Asterisks, "*") \
|
||||||
X(Hash, "#")
|
X(Hash, "#")
|
||||||
|
|
||||||
#define X(decl, str) decl,
|
#define X(decl, str) decl,
|
||||||
@ -381,12 +398,22 @@ void CPPTokeniser_SprintfToFileNoIndenting(CPPTokeniser *tokeniser, char const *
|
|||||||
va_end(va);
|
va_end(va);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPToken CPPTokeniser_NextToken(CPPTokeniser *tokeniser)
|
CPPToken CPPTokeniser_NextToken(CPPTokeniser *tokeniser, int amount = 1)
|
||||||
{
|
{
|
||||||
CPPToken result = tokeniser->tokens[tokeniser->tokens_index++];
|
CPPToken result = tokeniser->tokens[tokeniser->tokens_index];
|
||||||
if (result.type == CPPTokenType::LeftBrace) tokeniser->indent_level++;
|
if (result.type != CPPTokenType::EndOfStream)
|
||||||
else if (result.type == CPPTokenType::RightBrace) tokeniser->indent_level--;
|
{
|
||||||
assert(tokeniser->indent_level >= 0);
|
for (int i = 0; i < amount; i++)
|
||||||
|
{
|
||||||
|
result = tokeniser->tokens[tokeniser->tokens_index++];
|
||||||
|
if (result.type == CPPTokenType::LeftBrace) tokeniser->indent_level++;
|
||||||
|
else if (result.type == CPPTokenType::RightBrace) tokeniser->indent_level--;
|
||||||
|
assert(tokeniser->indent_level >= 0);
|
||||||
|
|
||||||
|
if (result.type == CPPTokenType::EndOfStream)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,9 +473,12 @@ CPPReflectMetadataArray ParseCPPReflectMeta(CPPTokeniser *tokeniser)
|
|||||||
{
|
{
|
||||||
CPPReflectMetadataArray result = {};
|
CPPReflectMetadataArray result = {};
|
||||||
CPPToken token = CPPTokeniser_NextToken(tokeniser);
|
CPPToken token = CPPTokeniser_NextToken(tokeniser);
|
||||||
if (!ExpectToken(token, CPPTokenType::OpenParen))
|
if (!ExpectToken(token, CPPTokenType::Identifier) || !IsIdentifierToken(token, STR_LITERAL("DQN_REFLECT_META")))
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
token = CPPTokeniser_NextToken(tokeniser);
|
||||||
|
if (!ExpectToken(token, CPPTokenType::OpenParen)) return result;
|
||||||
|
|
||||||
for (token = CPPTokeniser_NextToken(tokeniser);
|
for (token = CPPTokeniser_NextToken(tokeniser);
|
||||||
token.type != CPPTokenType::EndOfStream && token.type != CPPTokenType::CloseParen;
|
token.type != CPPTokenType::EndOfStream && token.type != CPPTokenType::CloseParen;
|
||||||
token = CPPTokeniser_NextToken(tokeniser))
|
token = CPPTokeniser_NextToken(tokeniser))
|
||||||
@ -478,14 +508,16 @@ CPPReflectMetadataArray ParseCPPReflectMeta(CPPTokeniser *tokeniser)
|
|||||||
while (token.type != CPPTokenType::EndOfStream && token.type != CPPTokenType::Comma)
|
while (token.type != CPPTokenType::EndOfStream && token.type != CPPTokenType::Comma)
|
||||||
token = CPPTokeniser_NextToken(tokeniser);
|
token = CPPTokeniser_NextToken(tokeniser);
|
||||||
|
|
||||||
if (token.type == CPPTokenType::EndOfStream)
|
|
||||||
CPPTokeniser_RewindToken(tokeniser);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseCPPEnum(CPPTokeniser *tokeniser)
|
void ParseCPPEnum(CPPTokeniser *tokeniser)
|
||||||
{
|
{
|
||||||
CPPToken token = CPPTokeniser_NextToken(tokeniser);
|
CPPToken token = CPPTokeniser_NextToken(tokeniser);
|
||||||
|
if (!ExpectToken(token, CPPTokenType::Identifier) || !IsIdentifierToken(token, STR_LITERAL("enum")))
|
||||||
|
return;
|
||||||
|
|
||||||
|
token = CPPTokeniser_NextToken(tokeniser);
|
||||||
b32 enum_is_struct_or_class = false;
|
b32 enum_is_struct_or_class = false;
|
||||||
|
|
||||||
if (IsIdentifierToken(token, STR_LITERAL("class")) ||
|
if (IsIdentifierToken(token, STR_LITERAL("class")) ||
|
||||||
@ -514,9 +546,9 @@ void ParseCPPEnum(CPPTokeniser *tokeniser)
|
|||||||
if (token.type == CPPTokenType::Identifier)
|
if (token.type == CPPTokenType::Identifier)
|
||||||
{
|
{
|
||||||
CPPToken enum_value = token;
|
CPPToken enum_value = token;
|
||||||
token = CPPTokeniser_NextToken(tokeniser);
|
CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser);
|
||||||
CPPReflectMetadataArray metadata_array = {};
|
CPPReflectMetadataArray metadata_array = {};
|
||||||
if (IsIdentifierToken(token, STR_LITERAL("DQN_REFLECT_META")))
|
if (IsIdentifierToken(peek_token, STR_LITERAL("DQN_REFLECT_META")))
|
||||||
{
|
{
|
||||||
has_metadata = true;
|
has_metadata = true;
|
||||||
metadata_array = ParseCPPReflectMeta(tokeniser);
|
metadata_array = ParseCPPReflectMeta(tokeniser);
|
||||||
@ -626,7 +658,7 @@ void ParseCPPEnum(CPPTokeniser *tokeniser)
|
|||||||
//
|
//
|
||||||
if (has_metadata)
|
if (has_metadata)
|
||||||
{
|
{
|
||||||
struct CPPDeclToValue
|
struct CPPDeclToMetaValue
|
||||||
{
|
{
|
||||||
StringLiteral cpp_decl;
|
StringLiteral cpp_decl;
|
||||||
StringLiteral value;
|
StringLiteral value;
|
||||||
@ -634,8 +666,8 @@ void ParseCPPEnum(CPPTokeniser *tokeniser)
|
|||||||
|
|
||||||
struct MetadataEntry
|
struct MetadataEntry
|
||||||
{
|
{
|
||||||
StringLiteral key;
|
StringLiteral key;
|
||||||
FixedArray<CPPDeclToValue, 32> cpp_decl_to_val;
|
FixedArray<CPPDeclToMetaValue, 32> cpp_decl_to_val;
|
||||||
};
|
};
|
||||||
|
|
||||||
FixedArray<MetadataEntry, 32> metadata_entries = {};
|
FixedArray<MetadataEntry, 32> metadata_entries = {};
|
||||||
@ -661,7 +693,7 @@ void ParseCPPEnum(CPPTokeniser *tokeniser)
|
|||||||
metadata_entry_to_append_to->key = reflect_entry.key;
|
metadata_entry_to_append_to->key = reflect_entry.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPDeclToValue decl_to_val = {};
|
CPPDeclToMetaValue decl_to_val = {};
|
||||||
decl_to_val.cpp_decl = StringLiteral(link->value.str, link->value.len);
|
decl_to_val.cpp_decl = StringLiteral(link->value.str, link->value.len);
|
||||||
decl_to_val.value = reflect_entry.value;
|
decl_to_val.value = reflect_entry.value;
|
||||||
FixedArray_Add(&metadata_entry_to_append_to->cpp_decl_to_val, decl_to_val);
|
FixedArray_Add(&metadata_entry_to_append_to->cpp_decl_to_val, decl_to_val);
|
||||||
@ -683,7 +715,7 @@ void ParseCPPEnum(CPPTokeniser *tokeniser)
|
|||||||
CPPTokeniser_SprintfToFile(tokeniser, "}\n\n");
|
CPPTokeniser_SprintfToFile(tokeniser, "}\n\n");
|
||||||
};
|
};
|
||||||
|
|
||||||
for (CPPDeclToValue const &decl_to_val : metadata.cpp_decl_to_val)
|
for (CPPDeclToMetaValue const &decl_to_val : metadata.cpp_decl_to_val)
|
||||||
{
|
{
|
||||||
StringLiteral const *cpp_decl = &decl_to_val.cpp_decl;
|
StringLiteral const *cpp_decl = &decl_to_val.cpp_decl;
|
||||||
StringLiteral const *value = &decl_to_val.value;
|
StringLiteral const *value = &decl_to_val.value;
|
||||||
@ -707,6 +739,101 @@ void ParseCPPEnum(CPPTokeniser *tokeniser)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CPPVariableDecl
|
||||||
|
{
|
||||||
|
StringLiteral type;
|
||||||
|
StringLiteral name;
|
||||||
|
b32 is_array;
|
||||||
|
int array_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ParseCPPStruct(CPPTokeniser *tokeniser)
|
||||||
|
{
|
||||||
|
CPPToken token = CPPTokeniser_NextToken(tokeniser);
|
||||||
|
if (!ExpectToken(token, CPPTokenType::Identifier) ||
|
||||||
|
(!IsIdentifierToken(token, STR_LITERAL("struct")) && !IsIdentifierToken(token, STR_LITERAL("class"))))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int const original_indent_level = tokeniser->indent_level;
|
||||||
|
token = CPPTokeniser_NextToken(tokeniser);
|
||||||
|
|
||||||
|
StringLiteral name = STR_LITERAL("");
|
||||||
|
if (token.type != CPPTokenType::LeftBrace)
|
||||||
|
{
|
||||||
|
if (!ExpectToken(token, CPPTokenType::Identifier)) return;
|
||||||
|
name = StringLiteral(token.str, token.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
FixedArray<CPPVariableDecl, 128> struct_members = {};
|
||||||
|
for (token = CPPTokeniser_NextToken(tokeniser);
|
||||||
|
tokeniser->indent_level != original_indent_level && token.type != CPPTokenType::EndOfStream;
|
||||||
|
token = CPPTokeniser_NextToken(tokeniser))
|
||||||
|
{
|
||||||
|
if (token.type == CPPTokenType::Identifier)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int asterisks_count = 0;
|
||||||
|
for (;; ++asterisks_count)
|
||||||
|
{
|
||||||
|
Token peek_token = CPPTokeniser_PeekToken(tokeniser);
|
||||||
|
if (peek_token == CPPTokenType::Asterisks) CPPTokeniser_NextToken(tokeniser);
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser);
|
||||||
|
if (peek_token.type == CPPTokenType::Identifier)
|
||||||
|
{
|
||||||
|
CPPVariableDecl *decl = FixedArray_Make(&struct_members, 1);
|
||||||
|
decl->type = StringLiteral(token.str, token.len);
|
||||||
|
decl->name = StringLiteral(peek_token.str, peek_token.len);
|
||||||
|
|
||||||
|
CPPTokeniser_NextToken(tokeniser);
|
||||||
|
peek_token = CPPTokeniser_PeekToken(tokeniser);
|
||||||
|
CPPReflectMetadataArray metadata_array = {};
|
||||||
|
if (IsIdentifierToken(token, STR_LITERAL("DQN_REFLECT_META")))
|
||||||
|
{
|
||||||
|
metadata_array = ParseCPPReflectMeta(tokeniser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "DqnReflect_Struct DqnReflect_Struct%.*s =\n{\n", name.len, name.str);
|
||||||
|
tokeniser->indent_level++;
|
||||||
|
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "\"%.*s\", // name \n", name.len, name.str);
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "DQN_REFLECT_CHAR_COUNT(\"%.*s\"), // name_len \n", name.len, name.str);
|
||||||
|
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "{ // members \n");
|
||||||
|
tokeniser->indent_level++;
|
||||||
|
for (CPPVariableDecl const &decl : struct_members)
|
||||||
|
{
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "{\n");
|
||||||
|
tokeniser->indent_level++;
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "\"%.*s\",\n", decl.type.len, decl.type.str);
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "DQN_REFLECT_CHAR_COUNT(\"%.*s\"),\n", decl.type.len, decl.type.str);
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "\"%.*s\",\n", decl.name.len, decl.name.str);
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "DQN_REFLECT_CHAR_COUNT(\"%.*s\"),\n", decl.name.len, decl.name.str);
|
||||||
|
tokeniser->indent_level--;
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "},\n");
|
||||||
|
}
|
||||||
|
tokeniser->indent_level--;
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "},\n");
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "%d // members_len \n", (int)struct_members.len);
|
||||||
|
|
||||||
|
tokeniser->indent_level--;
|
||||||
|
CPPTokeniser_SprintfToFile(tokeniser, "};\n");
|
||||||
|
|
||||||
|
int break_here = 5;
|
||||||
|
(void)break_here;
|
||||||
|
assert(tokeniser->indent_level == 0);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
@ -728,6 +855,9 @@ int main(int argc, char *argv[])
|
|||||||
"#ifndef DQN_REFLECT_GENERATED_H\n"
|
"#ifndef DQN_REFLECT_GENERATED_H\n"
|
||||||
"#define DQN_REFLECT_GENERATED_H\n\n"
|
"#define DQN_REFLECT_GENERATED_H\n\n"
|
||||||
"// This is an auto generated file using Dqn_Reflect\n"
|
"// This is an auto generated file using Dqn_Reflect\n"
|
||||||
|
"\n"
|
||||||
|
"#define DQN_REFLECT_ARRAY_COUNT(array) sizeof(array)/sizeof((array)[0])\n"
|
||||||
|
"#define DQN_REFLECT_CHAR_COUNT(str) (DQN_REFLECT_ARRAY_COUNT(str) - 1)\n"
|
||||||
"\n");
|
"\n");
|
||||||
|
|
||||||
for (usize arg_index = 1; arg_index < argc; ++arg_index)
|
for (usize arg_index = 1; arg_index < argc; ++arg_index)
|
||||||
@ -798,6 +928,8 @@ int main(int argc, char *argv[])
|
|||||||
ptr = StrFind(buffer, REFLECT_MARKER))
|
ptr = StrFind(buffer, REFLECT_MARKER))
|
||||||
{
|
{
|
||||||
ptr += REFLECT_MARKER.len;
|
ptr += REFLECT_MARKER.len;
|
||||||
|
int indent_level = 0;
|
||||||
|
bool started_lexing_scope = false;
|
||||||
for (; ptr;)
|
for (; ptr;)
|
||||||
{
|
{
|
||||||
while (CharIsWhitespace(ptr[0])) ptr++;
|
while (CharIsWhitespace(ptr[0])) ptr++;
|
||||||
@ -808,8 +940,8 @@ int main(int argc, char *argv[])
|
|||||||
token->len = 1;
|
token->len = 1;
|
||||||
switch(token->str[0])
|
switch(token->str[0])
|
||||||
{
|
{
|
||||||
case '{': { token->type = CPPTokenType::LeftBrace; } break;
|
case '{': { token->type = CPPTokenType::LeftBrace; started_lexing_scope = true; indent_level++; } break;
|
||||||
case '}': { token->type = CPPTokenType::RightBrace; } break;
|
case '}': { token->type = CPPTokenType::RightBrace; indent_level--; } break;
|
||||||
case '(': { token->type = CPPTokenType::OpenParen; } break;
|
case '(': { token->type = CPPTokenType::OpenParen; } break;
|
||||||
case ')': { token->type = CPPTokenType::CloseParen; } break;
|
case ')': { token->type = CPPTokenType::CloseParen; } break;
|
||||||
case ',': { token->type = CPPTokenType::Comma; } break;
|
case ',': { token->type = CPPTokenType::Comma; } break;
|
||||||
@ -818,11 +950,13 @@ int main(int argc, char *argv[])
|
|||||||
case '<': { token->type = CPPTokenType::LessThan; } break;
|
case '<': { token->type = CPPTokenType::LessThan; } break;
|
||||||
case '>': { token->type = CPPTokenType::GreaterThan; } break;
|
case '>': { token->type = CPPTokenType::GreaterThan; } break;
|
||||||
case ':': { token->type = CPPTokenType::Colon; } break;
|
case ':': { token->type = CPPTokenType::Colon; } break;
|
||||||
|
case '*': { token->type = CPPTokenType::Asterisks; } break;
|
||||||
case '/':
|
case '/':
|
||||||
{
|
{
|
||||||
token->type = CPPTokenType::FwdSlash;
|
token->type = CPPTokenType::FwdSlash;
|
||||||
if (ptr[0] == '/')
|
if (ptr[0] == '/')
|
||||||
{
|
{
|
||||||
|
ptr++;
|
||||||
while (ptr[0] == ' ' || ptr[0] == '\t') ptr++;
|
while (ptr[0] == ' ' || ptr[0] == '\t') ptr++;
|
||||||
token->str = ptr;
|
token->str = ptr;
|
||||||
while (ptr[0] != '\n') ptr++;
|
while (ptr[0] != '\n') ptr++;
|
||||||
@ -880,9 +1014,10 @@ int main(int argc, char *argv[])
|
|||||||
*token = {};
|
*token = {};
|
||||||
tokeniser.tokens_len--;
|
tokeniser.tokens_len--;
|
||||||
}
|
}
|
||||||
else if (token->type == CPPTokenType::SemiColon)
|
else
|
||||||
{
|
{
|
||||||
break;
|
if (started_lexing_scope && indent_level == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -893,20 +1028,30 @@ int main(int argc, char *argv[])
|
|||||||
CPPToken *sentinel = CPPTokeniser_MakeToken(&tokeniser);
|
CPPToken *sentinel = CPPTokeniser_MakeToken(&tokeniser);
|
||||||
sentinel->type = CPPTokenType::EndOfStream;
|
sentinel->type = CPPTokenType::EndOfStream;
|
||||||
|
|
||||||
for (CPPToken token = CPPTokeniser_NextToken(&tokeniser);
|
for (CPPToken token = CPPTokeniser_PeekToken(&tokeniser);
|
||||||
token.type != CPPTokenType::EndOfStream;
|
;
|
||||||
token = CPPTokeniser_NextToken(&tokeniser))
|
token = CPPTokeniser_PeekToken(&tokeniser))
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
Token const *token = tokens + index;
|
Token const *token = tokens + index;
|
||||||
fprintf(stdout, "%.*s", token->len, token->str);
|
fprintf(stdout, "%.*s", token->len, token->str);
|
||||||
if (index < (tokens_index - 1)) fprintf(stdout, " -> ");
|
if (index < (tokens_index - 1)) fprintf(stdout, " -> ");
|
||||||
#endif
|
#endif
|
||||||
if (token.type == CPPTokenType::Identifier)
|
if (IsIdentifierToken(token, STR_LITERAL("enum")))
|
||||||
{
|
{
|
||||||
if (StrCmp(StringLiteral(token.str, token.len), STR_LITERAL("enum")))
|
ParseCPPEnum(&tokeniser);
|
||||||
ParseCPPEnum(&tokeniser);
|
|
||||||
}
|
}
|
||||||
|
else if (IsIdentifierToken(token, STR_LITERAL("struct")) || IsIdentifierToken(token, STR_LITERAL("class")))
|
||||||
|
{
|
||||||
|
ParseCPPStruct(&tokeniser);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
token = CPPTokeniser_NextToken(&tokeniser);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.type == CPPTokenType::EndOfStream)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(output_file, "#endif // DQN_REFLECT_DISABLE_%.*s\n\n",
|
fprintf(output_file, "#endif // DQN_REFLECT_DISABLE_%.*s\n\n",
|
||||||
|
@ -1,6 +1,28 @@
|
|||||||
DQN_REFLECT enum struct OpenGLShader
|
enum struct OpenGLShader
|
||||||
{
|
{
|
||||||
Invalid,
|
Invalid,
|
||||||
Rect DQN_REFLECT_META(VertexShaderFilePath = "Rect.vert", FragmentShaderFilePath = "Rect.frag"),
|
Rect (VertexShaderFilePath = "Rect.vert", FragmentShaderFilePath = "Rect.frag"),
|
||||||
Text DQN_REFLECT_META(VertexShaderFilePath = "Text.vert", FragmentShaderFilePath = "Text.frag"),
|
Text (VertexShaderFilePath = "Text.vert", FragmentShaderFilePath = "Text.frag"),
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define EXAMPLE_MACRO \
|
||||||
|
X(EndOfStream, "End Of Stream") \
|
||||||
|
X(Hash, "#")
|
||||||
|
|
||||||
|
#define MAXIMUM_MACRO(a, b) (a > b) ? (a) : (b)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DQN_REFLECT struct OpenGLState
|
||||||
|
{
|
||||||
|
// #if 0
|
||||||
|
// #endif
|
||||||
|
// u32 ebo, vbo, vao;
|
||||||
|
// u32 shaders[(int)OpenGLShader::Count];
|
||||||
|
V4 draw_color;
|
||||||
|
V3 lighting_ambient_coeff;
|
||||||
|
// u8 **bitmaps;
|
||||||
|
// FixedArray<RendererLight, 32> lights;
|
||||||
|
// FixedArray<Mat4, 32> camera_matrixes;
|
||||||
|
int draw_call_count;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user