diff --git a/src/.clang-format b/src/.clang-format index 947e6c7..c7a99e9 100644 --- a/src/.clang-format +++ b/src/.clang-format @@ -1,3 +1,9 @@ BasedOnStyle: Microsoft IndentWidth: 4 -NamespaceIndentation: NI_All +NamespaceIndentation: All +PointerAlignment: Left +AllowShortIfStatementsOnASingleLine: WithoutElse +BreakBeforeBraces: Allman +BinPackParameters: false +BinPackArguments: false + diff --git a/src/engine/Shared.h b/src/engine/Shared.h index 9a5ac21..ac08a07 100644 --- a/src/engine/Shared.h +++ b/src/engine/Shared.h @@ -3,39 +3,39 @@ struct SharedWindowData { - void* Handle = nullptr; - int32_t WindowWidth = 1920; - int32_t WindowHeight = 1080; + void* Handle = nullptr; + int32_t WindowWidth = 1920; + int32_t WindowHeight = 1080; + bool HeldScanCodes[512]{0}; }; struct FileChangeNotification { - wchar_t FileName[128]{0}; + wchar_t FileName[128]{0}; }; struct SharedDevData { - uint32_t ChangedShaderCount = 0; - FileChangeNotification ChangedShaders[16]; + uint32_t ChangedShaderCount = 0; + FileChangeNotification ChangedShaders[16]; }; struct GameData { - void* PermanentStorage = nullptr; - uint64_t PermanentStorageSize = 0; + void* PermanentStorage = nullptr; + uint64_t PermanentStorageSize = 0; - void* EntityStorage = nullptr; - uint64_t EntityStorageSize = 0; + void* EntityStorage = nullptr; + uint64_t EntityStorageSize = 0; }; struct SharedData { - SharedDevData Dev; - SharedWindowData Window; - GameData Game; + SharedDevData Dev; + SharedWindowData Window; + GameData Game; }; typedef void (*Startup)(SharedData& shared); typedef void (*Update)(); typedef void (*Shutdown)(); - diff --git a/src/engine/Window.cpp b/src/engine/Window.cpp index 928c0e7..d78424a 100644 --- a/src/engine/Window.cpp +++ b/src/engine/Window.cpp @@ -1,58 +1,70 @@ -#include "Window.h" #include "SDL3/SDL_events.h" #include "Shared.h" -#include +#include "Window.h" #include +#include void EngineWindow::Startup(SharedWindowData& shared) { - if (!SDL_Init(SDL_INIT_VIDEO)) - { - printf("Failed to init SDL!\n"); - return; - } - Window = SDL_CreateWindow("SDL", shared.WindowWidth, shared.WindowHeight, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL); - if (Window == nullptr) - { - printf("Failed to init SDL Window!\n"); - return; - } - auto props = SDL_GetWindowProperties(Window); - SDL_EnumerateProperties(props, [](void*, SDL_PropertiesID id, const char* name) - { - printf("Prop: %s\n", name); - }, nullptr); - shared.Handle = SDL_GetPointerProperty(props, "SDL.window.win32.hwnd", nullptr); - if (shared.Handle == nullptr) - { - printf("Failed to get window pointer!\n"); - return; - } - + if (!SDL_Init(SDL_INIT_VIDEO)) + { + printf("Failed to init SDL!\n"); + return; + } + Window = SDL_CreateWindow("SDL", shared.WindowWidth, shared.WindowHeight, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL); + if (Window == nullptr) + { + printf("Failed to init SDL Window!\n"); + return; + } + auto props = SDL_GetWindowProperties(Window); + SDL_EnumerateProperties( + props, [](void*, SDL_PropertiesID id, const char* name) { printf("Prop: %s\n", name); }, nullptr); + shared.Handle = SDL_GetPointerProperty(props, "SDL.window.win32.hwnd", nullptr); + if (shared.Handle == nullptr) + { + printf("Failed to get window pointer!\n"); + return; + } } -void EngineWindow::Update(SharedWindowData& Shared) +void EngineWindow::Update(SharedWindowData& shared) { - SDL_Event evt; - while (SDL_PollEvent(&evt)) - { - switch (evt.type) - { - case SDL_EVENT_WINDOW_RESIZED: - { - SDL_GetWindowSize(Window, &Shared.WindowWidth, &Shared.WindowHeight); - break; - } - case SDL_EVENT_WINDOW_CLOSE_REQUESTED: - { - CloseRequested = true; - break; - } - } - } + SDL_Event evt; + while (SDL_PollEvent(&evt)) + { + switch (evt.type) + { + case SDL_EVENT_WINDOW_RESIZED: + { + SDL_GetWindowSize(Window, &shared.WindowWidth, &shared.WindowHeight); + break; + } + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + { + CloseRequested = true; + break; + } + case SDL_EVENT_KEY_DOWN: + { + shared.HeldScanCodes[evt.key.scancode] = true; + break; + } + case SDL_EVENT_KEY_UP: + { + shared.HeldScanCodes[evt.key.scancode] = false; + break; + } + case SDL_EVENT_MOUSE_MOTION: + { + } + default: + break; + } + } } void EngineWindow::Shutdown() { - SDL_Quit(); + SDL_Quit(); } diff --git a/src/engine/test.txt b/src/engine/test.txt new file mode 100644 index 0000000..57d55c2 --- /dev/null +++ b/src/engine/test.txt @@ -0,0 +1,236 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAfterAttributes: Never +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +... + diff --git a/src/game/Global.cpp b/src/game/Global.cpp index a4293eb..7dd1cb5 100644 --- a/src/game/Global.cpp +++ b/src/game/Global.cpp @@ -5,56 +5,91 @@ namespace { - SharedData* SharedInstance = nullptr; - Game::GameInstance* GameInst = nullptr; -} + SharedData* SharedInstance = nullptr; + Game::GameInstance* GameInst = nullptr; +} // namespace Quat Quat::FromEuler(float x, float y, float z) { - x *= bx::kPi / 180.0f; - y *= bx::kPi / 180.0f; - z *= bx::kPi / 180.0f; + x *= bx::kPi / 180.0f; + y *= bx::kPi / 180.0f; + z *= bx::kPi / 180.0f; - float cX = bx::cos(x); - float cY = bx::cos(y); - float cZ = bx::cos(z); - float sX = bx::sin(x); - float sY = bx::sin(y); - float sZ = bx::sin(z); + float cX = bx::cos(x); + float cY = bx::cos(y); + float cZ = bx::cos(z); + float sX = bx::sin(x); + float sY = bx::sin(y); + float sZ = bx::sin(z); - return Quat{ - cX * cY * cZ - sX * sY * sZ, - sY * cX * cZ - sX * sZ * cY, - sX * sY * cZ + sZ * cX * cY, - sX * cY * cZ + sY * sZ * cX }; + return Quat{cX * cY * cZ - sX * sY * sZ, + sY * cX * cZ - sX * sZ * cY, + sX * sY * cZ + sZ * cX * cY, + sX * cY * cZ + sY * sZ * cX}; } Quat Quat::FromEuler(Vec3 rot) { - return Quat::FromEuler(rot.X, rot.Y, rot.Z); + return Quat::FromEuler(rot.X, rot.Y, rot.Z); +} + +void Mat4::CreateTransform(float* out, Vec3 pos, Quat rot, Vec3 scale) +{ + if (out == nullptr) return; + float rMat[16]{0}; + float tMat[16]{0}; + float sMat[16]{0}; + bx::mtxFromQuaternion(rMat, bx::Quaternion{rot.X, rot.Y, rot.Z, rot.W}); + bx::mtxTranslate(tMat, pos.X, pos.Y, pos.Z); + bx::mtxScale(sMat, scale.X, scale.Y, scale.Z); + float buf[16]{0}; + bx::mtxMul(buf, rMat, sMat); + bx::mtxMul(out, buf, tMat); +} + +void Mat4::Translate(Vec3 offset) +{ + M[12] += offset.X; + M[13] += offset.Y; + M[14] += offset.Z; +} + +Vec3 Mat4::Right() +{ + return {M[0], M[1], M[2]}; +} + +Vec3 Mat4::Up() +{ + return {M[4], M[5], M[6]}; +} + +Vec3 Mat4::Forward() +{ + return {M[8], M[9], M[10]}; } namespace Game { - SharedData& GetShared() - { - assert(SharedInstance != nullptr); - return *SharedInstance; - } + SharedData& GetShared() + { + assert(SharedInstance != nullptr); + return *SharedInstance; + } - void SetShared(SharedData& instance) - { - SharedInstance = &instance; - } + void SetShared(SharedData& instance) + { + SharedInstance = &instance; + } - GameInstance& GetInstance() - { - assert(GameInst != nullptr); - return *GameInst; - } + GameInstance& GetInstance() + { + assert(GameInst != nullptr); + return *GameInst; + } - void SetInstance(Game::GameInstance& instance) - { - GameInst = &instance; - } -} + void SetInstance(Game::GameInstance& instance) + { + GameInst = &instance; + } +} // namespace Game diff --git a/src/game/Global.h b/src/game/Global.h index f6936a5..3fe64c7 100644 --- a/src/game/Global.h +++ b/src/game/Global.h @@ -1,60 +1,84 @@ #pragma once +#include #include struct SharedData; struct IVec2 { - int32_t X = 0; - int32_t Y = 0; + int32_t X = 0; + int32_t Y = 0; }; struct IVec3 { - int32_t X = 0; - int32_t Y = 0; + int32_t X = 0; + int32_t Y = 0; }; struct Vec2 { - float X = 0.0f; - float Y = 0.0f; + float X = 0.0f; + float Y = 0.0f; }; struct Vec3 { - float X = 0.0f; - float Y = 0.0f; - float Z = 0.0f; + float X = 0.0f; + float Y = 0.0f; + float Z = 0.0f; + + bx::Vec3 ToBX() + { + return {X, Y, Z}; + }; }; struct Quat { - float X = 0.0f; - float Y = 0.0f; - float Z = 0.0f; - float W = 1.0f; + float X = 0.0f; + float Y = 0.0f; + float Z = 0.0f; + float W = 1.0f; - static Quat FromEuler(float x, float y, float z); - static Quat FromEuler(Vec3 rot); + static Quat FromEuler(float x, float y, float z); + static Quat FromEuler(Vec3 rot); }; struct Mat4 { - float M[16] { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, - }; + float M[16]{ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + }; + + static void CreateTransform(float* out, Vec3 pos, Quat rot = {}, Vec3 scale = {1.0f, 1.0f, 1.0f}); + void Translate(Vec3 offset); + Vec3 Right(); + Vec3 Up(); + Vec3 Forward(); }; namespace Game { - struct GameInstance; - - SharedData& GetShared(); - void SetShared(SharedData& instance); - GameInstance& GetInstance(); - void SetInstance(GameInstance& instance); -} + struct GameInstance; + + SharedData& GetShared(); + void SetShared(SharedData& instance); + GameInstance& GetInstance(); + void SetInstance(GameInstance& instance); +} // namespace Game diff --git a/src/game/Input.cpp b/src/game/Input.cpp new file mode 100644 index 0000000..9ec5e49 --- /dev/null +++ b/src/game/Input.cpp @@ -0,0 +1,11 @@ +#include "../engine/Shared.h" +#include "Global.h" +#include "Input.h" + +namespace Game +{ + bool GetKey(ScanCode key) + { + return GetShared().Window.HeldScanCodes[(int32_t)key]; + } +} // namespace Game diff --git a/src/game/Input.h b/src/game/Input.h new file mode 100644 index 0000000..dd35a1a --- /dev/null +++ b/src/game/Input.h @@ -0,0 +1,381 @@ +#pragma once + +enum class ScanCode +{ + SDL_SCANCODE_UNKNOWN = 0, + + /** + * \name Usage page 0x07 + * + * These values are from usage page 0x07 (USB keyboard page). + */ + /* @{ */ + + SDL_SCANCODE_A = 4, + SDL_SCANCODE_B = 5, + SDL_SCANCODE_C = 6, + SDL_SCANCODE_D = 7, + SDL_SCANCODE_E = 8, + SDL_SCANCODE_F = 9, + SDL_SCANCODE_G = 10, + SDL_SCANCODE_H = 11, + SDL_SCANCODE_I = 12, + SDL_SCANCODE_J = 13, + SDL_SCANCODE_K = 14, + SDL_SCANCODE_L = 15, + SDL_SCANCODE_M = 16, + SDL_SCANCODE_N = 17, + SDL_SCANCODE_O = 18, + SDL_SCANCODE_P = 19, + SDL_SCANCODE_Q = 20, + SDL_SCANCODE_R = 21, + SDL_SCANCODE_S = 22, + SDL_SCANCODE_T = 23, + SDL_SCANCODE_U = 24, + SDL_SCANCODE_V = 25, + SDL_SCANCODE_W = 26, + SDL_SCANCODE_X = 27, + SDL_SCANCODE_Y = 28, + SDL_SCANCODE_Z = 29, + + SDL_SCANCODE_1 = 30, + SDL_SCANCODE_2 = 31, + SDL_SCANCODE_3 = 32, + SDL_SCANCODE_4 = 33, + SDL_SCANCODE_5 = 34, + SDL_SCANCODE_6 = 35, + SDL_SCANCODE_7 = 36, + SDL_SCANCODE_8 = 37, + SDL_SCANCODE_9 = 38, + SDL_SCANCODE_0 = 39, + + SDL_SCANCODE_RETURN = 40, + SDL_SCANCODE_ESCAPE = 41, + SDL_SCANCODE_BACKSPACE = 42, + SDL_SCANCODE_TAB = 43, + SDL_SCANCODE_SPACE = 44, + + SDL_SCANCODE_MINUS = 45, + SDL_SCANCODE_EQUALS = 46, + SDL_SCANCODE_LEFTBRACKET = 47, + SDL_SCANCODE_RIGHTBRACKET = 48, + SDL_SCANCODE_BACKSLASH = 49, /**< Located at the lower left of the return + * key on ISO keyboards and at the right end + * of the QWERTY row on ANSI keyboards. + * Produces REVERSE SOLIDUS (backslash) and + * VERTICAL LINE in a US layout, REVERSE + * SOLIDUS and VERTICAL LINE in a UK Mac + * layout, NUMBER SIGN and TILDE in a UK + * Windows layout, DOLLAR SIGN and POUND SIGN + * in a Swiss German layout, NUMBER SIGN and + * APOSTROPHE in a German layout, GRAVE + * ACCENT and POUND SIGN in a French Mac + * layout, and ASTERISK and MICRO SIGN in a + * French Windows layout. + */ + SDL_SCANCODE_NONUSHASH = 50, /**< ISO USB keyboards actually use this code + * instead of 49 for the same key, but all + * OSes I've seen treat the two codes + * identically. So, as an implementor, unless + * your keyboard generates both of those + * codes and your OS treats them differently, + * you should generate SDL_SCANCODE_BACKSLASH + * instead of this code. As a user, you + * should not rely on this code because SDL + * will never generate it with most (all?) + * keyboards. + */ + SDL_SCANCODE_SEMICOLON = 51, + SDL_SCANCODE_APOSTROPHE = 52, + SDL_SCANCODE_GRAVE = 53, /**< Located in the top left corner (on both ANSI + * and ISO keyboards). Produces GRAVE ACCENT and + * TILDE in a US Windows layout and in US and UK + * Mac layouts on ANSI keyboards, GRAVE ACCENT + * and NOT SIGN in a UK Windows layout, SECTION + * SIGN and PLUS-MINUS SIGN in US and UK Mac + * layouts on ISO keyboards, SECTION SIGN and + * DEGREE SIGN in a Swiss German layout (Mac: + * only on ISO keyboards), CIRCUMFLEX ACCENT and + * DEGREE SIGN in a German layout (Mac: only on + * ISO keyboards), SUPERSCRIPT TWO and TILDE in a + * French Windows layout, COMMERCIAL AT and + * NUMBER SIGN in a French Mac layout on ISO + * keyboards, and LESS-THAN SIGN and GREATER-THAN + * SIGN in a Swiss German, German, or French Mac + * layout on ANSI keyboards. + */ + SDL_SCANCODE_COMMA = 54, + SDL_SCANCODE_PERIOD = 55, + SDL_SCANCODE_SLASH = 56, + + SDL_SCANCODE_CAPSLOCK = 57, + + SDL_SCANCODE_F1 = 58, + SDL_SCANCODE_F2 = 59, + SDL_SCANCODE_F3 = 60, + SDL_SCANCODE_F4 = 61, + SDL_SCANCODE_F5 = 62, + SDL_SCANCODE_F6 = 63, + SDL_SCANCODE_F7 = 64, + SDL_SCANCODE_F8 = 65, + SDL_SCANCODE_F9 = 66, + SDL_SCANCODE_F10 = 67, + SDL_SCANCODE_F11 = 68, + SDL_SCANCODE_F12 = 69, + + SDL_SCANCODE_PRINTSCREEN = 70, + SDL_SCANCODE_SCROLLLOCK = 71, + SDL_SCANCODE_PAUSE = 72, + SDL_SCANCODE_INSERT = 73, /**< insert on PC, help on some Mac keyboards (but + does send code 73, not 117) */ + SDL_SCANCODE_HOME = 74, + SDL_SCANCODE_PAGEUP = 75, + SDL_SCANCODE_DELETE = 76, + SDL_SCANCODE_END = 77, + SDL_SCANCODE_PAGEDOWN = 78, + SDL_SCANCODE_RIGHT = 79, + SDL_SCANCODE_LEFT = 80, + SDL_SCANCODE_DOWN = 81, + SDL_SCANCODE_UP = 82, + + SDL_SCANCODE_NUMLOCKCLEAR = 83, /**< num lock on PC, clear on Mac keyboards + */ + SDL_SCANCODE_KP_DIVIDE = 84, + SDL_SCANCODE_KP_MULTIPLY = 85, + SDL_SCANCODE_KP_MINUS = 86, + SDL_SCANCODE_KP_PLUS = 87, + SDL_SCANCODE_KP_ENTER = 88, + SDL_SCANCODE_KP_1 = 89, + SDL_SCANCODE_KP_2 = 90, + SDL_SCANCODE_KP_3 = 91, + SDL_SCANCODE_KP_4 = 92, + SDL_SCANCODE_KP_5 = 93, + SDL_SCANCODE_KP_6 = 94, + SDL_SCANCODE_KP_7 = 95, + SDL_SCANCODE_KP_8 = 96, + SDL_SCANCODE_KP_9 = 97, + SDL_SCANCODE_KP_0 = 98, + SDL_SCANCODE_KP_PERIOD = 99, + + SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO + * keyboards have over ANSI ones, + * located between left shift and Y. + * Produces GRAVE ACCENT and TILDE in a + * US or UK Mac layout, REVERSE SOLIDUS + * (backslash) and VERTICAL LINE in a + * US or UK Windows layout, and + * LESS-THAN SIGN and GREATER-THAN SIGN + * in a Swiss German, German, or French + * layout. */ + SDL_SCANCODE_APPLICATION = 101, /**< windows contextual menu, compose */ + SDL_SCANCODE_POWER = 102, /**< The USB document says this is a status flag, + * not a physical key - but some Mac keyboards + * do have a power key. */ + SDL_SCANCODE_KP_EQUALS = 103, + SDL_SCANCODE_F13 = 104, + SDL_SCANCODE_F14 = 105, + SDL_SCANCODE_F15 = 106, + SDL_SCANCODE_F16 = 107, + SDL_SCANCODE_F17 = 108, + SDL_SCANCODE_F18 = 109, + SDL_SCANCODE_F19 = 110, + SDL_SCANCODE_F20 = 111, + SDL_SCANCODE_F21 = 112, + SDL_SCANCODE_F22 = 113, + SDL_SCANCODE_F23 = 114, + SDL_SCANCODE_F24 = 115, + SDL_SCANCODE_EXECUTE = 116, + SDL_SCANCODE_HELP = 117, /**< AL Integrated Help Center */ + SDL_SCANCODE_MENU = 118, /**< Menu (show menu) */ + SDL_SCANCODE_SELECT = 119, + SDL_SCANCODE_STOP = 120, /**< AC Stop */ + SDL_SCANCODE_AGAIN = 121, /**< AC Redo/Repeat */ + SDL_SCANCODE_UNDO = 122, /**< AC Undo */ + SDL_SCANCODE_CUT = 123, /**< AC Cut */ + SDL_SCANCODE_COPY = 124, /**< AC Copy */ + SDL_SCANCODE_PASTE = 125, /**< AC Paste */ + SDL_SCANCODE_FIND = 126, /**< AC Find */ + SDL_SCANCODE_MUTE = 127, + SDL_SCANCODE_VOLUMEUP = 128, + SDL_SCANCODE_VOLUMEDOWN = 129, + /* not sure whether there's a reason to enable these */ + /* SDL_SCANCODE_LOCKINGCAPSLOCK = 130, */ + /* SDL_SCANCODE_LOCKINGNUMLOCK = 131, */ + /* SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, */ + SDL_SCANCODE_KP_COMMA = 133, + SDL_SCANCODE_KP_EQUALSAS400 = 134, + + SDL_SCANCODE_INTERNATIONAL1 = 135, /**< used on Asian keyboards, see + footnotes in USB doc */ + SDL_SCANCODE_INTERNATIONAL2 = 136, + SDL_SCANCODE_INTERNATIONAL3 = 137, /**< Yen */ + SDL_SCANCODE_INTERNATIONAL4 = 138, + SDL_SCANCODE_INTERNATIONAL5 = 139, + SDL_SCANCODE_INTERNATIONAL6 = 140, + SDL_SCANCODE_INTERNATIONAL7 = 141, + SDL_SCANCODE_INTERNATIONAL8 = 142, + SDL_SCANCODE_INTERNATIONAL9 = 143, + SDL_SCANCODE_LANG1 = 144, /**< Hangul/English toggle */ + SDL_SCANCODE_LANG2 = 145, /**< Hanja conversion */ + SDL_SCANCODE_LANG3 = 146, /**< Katakana */ + SDL_SCANCODE_LANG4 = 147, /**< Hiragana */ + SDL_SCANCODE_LANG5 = 148, /**< Zenkaku/Hankaku */ + SDL_SCANCODE_LANG6 = 149, /**< reserved */ + SDL_SCANCODE_LANG7 = 150, /**< reserved */ + SDL_SCANCODE_LANG8 = 151, /**< reserved */ + SDL_SCANCODE_LANG9 = 152, /**< reserved */ + + SDL_SCANCODE_ALTERASE = 153, /**< Erase-Eaze */ + SDL_SCANCODE_SYSREQ = 154, + SDL_SCANCODE_CANCEL = 155, /**< AC Cancel */ + SDL_SCANCODE_CLEAR = 156, + SDL_SCANCODE_PRIOR = 157, + SDL_SCANCODE_RETURN2 = 158, + SDL_SCANCODE_SEPARATOR = 159, + SDL_SCANCODE_OUT = 160, + SDL_SCANCODE_OPER = 161, + SDL_SCANCODE_CLEARAGAIN = 162, + SDL_SCANCODE_CRSEL = 163, + SDL_SCANCODE_EXSEL = 164, + + SDL_SCANCODE_KP_00 = 176, + SDL_SCANCODE_KP_000 = 177, + SDL_SCANCODE_THOUSANDSSEPARATOR = 178, + SDL_SCANCODE_DECIMALSEPARATOR = 179, + SDL_SCANCODE_CURRENCYUNIT = 180, + SDL_SCANCODE_CURRENCYSUBUNIT = 181, + SDL_SCANCODE_KP_LEFTPAREN = 182, + SDL_SCANCODE_KP_RIGHTPAREN = 183, + SDL_SCANCODE_KP_LEFTBRACE = 184, + SDL_SCANCODE_KP_RIGHTBRACE = 185, + SDL_SCANCODE_KP_TAB = 186, + SDL_SCANCODE_KP_BACKSPACE = 187, + SDL_SCANCODE_KP_A = 188, + SDL_SCANCODE_KP_B = 189, + SDL_SCANCODE_KP_C = 190, + SDL_SCANCODE_KP_D = 191, + SDL_SCANCODE_KP_E = 192, + SDL_SCANCODE_KP_F = 193, + SDL_SCANCODE_KP_XOR = 194, + SDL_SCANCODE_KP_POWER = 195, + SDL_SCANCODE_KP_PERCENT = 196, + SDL_SCANCODE_KP_LESS = 197, + SDL_SCANCODE_KP_GREATER = 198, + SDL_SCANCODE_KP_AMPERSAND = 199, + SDL_SCANCODE_KP_DBLAMPERSAND = 200, + SDL_SCANCODE_KP_VERTICALBAR = 201, + SDL_SCANCODE_KP_DBLVERTICALBAR = 202, + SDL_SCANCODE_KP_COLON = 203, + SDL_SCANCODE_KP_HASH = 204, + SDL_SCANCODE_KP_SPACE = 205, + SDL_SCANCODE_KP_AT = 206, + SDL_SCANCODE_KP_EXCLAM = 207, + SDL_SCANCODE_KP_MEMSTORE = 208, + SDL_SCANCODE_KP_MEMRECALL = 209, + SDL_SCANCODE_KP_MEMCLEAR = 210, + SDL_SCANCODE_KP_MEMADD = 211, + SDL_SCANCODE_KP_MEMSUBTRACT = 212, + SDL_SCANCODE_KP_MEMMULTIPLY = 213, + SDL_SCANCODE_KP_MEMDIVIDE = 214, + SDL_SCANCODE_KP_PLUSMINUS = 215, + SDL_SCANCODE_KP_CLEAR = 216, + SDL_SCANCODE_KP_CLEARENTRY = 217, + SDL_SCANCODE_KP_BINARY = 218, + SDL_SCANCODE_KP_OCTAL = 219, + SDL_SCANCODE_KP_DECIMAL = 220, + SDL_SCANCODE_KP_HEXADECIMAL = 221, + + SDL_SCANCODE_LCTRL = 224, + SDL_SCANCODE_LSHIFT = 225, + SDL_SCANCODE_LALT = 226, /**< alt, option */ + SDL_SCANCODE_LGUI = 227, /**< windows, command (apple), meta */ + SDL_SCANCODE_RCTRL = 228, + SDL_SCANCODE_RSHIFT = 229, + SDL_SCANCODE_RALT = 230, /**< alt gr, option */ + SDL_SCANCODE_RGUI = 231, /**< windows, command (apple), meta */ + + SDL_SCANCODE_MODE = 257, /**< I'm not sure if this is really not covered + * by any of the above, but since there's a + * special SDL_KMOD_MODE for it I'm adding it here + */ + + /* @} */ /* Usage page 0x07 */ + + /** + * \name Usage page 0x0C + * + * These values are mapped from usage page 0x0C (USB consumer page). + * + * There are way more keys in the spec than we can represent in the + * current scancode range, so pick the ones that commonly come up in + * real world usage. + */ + /* @{ */ + + SDL_SCANCODE_SLEEP = 258, /**< Sleep */ + SDL_SCANCODE_WAKE = 259, /**< Wake */ + + SDL_SCANCODE_CHANNEL_INCREMENT = 260, /**< Channel Increment */ + SDL_SCANCODE_CHANNEL_DECREMENT = 261, /**< Channel Decrement */ + + SDL_SCANCODE_MEDIA_PLAY = 262, /**< Play */ + SDL_SCANCODE_MEDIA_PAUSE = 263, /**< Pause */ + SDL_SCANCODE_MEDIA_RECORD = 264, /**< Record */ + SDL_SCANCODE_MEDIA_FAST_FORWARD = 265, /**< Fast Forward */ + SDL_SCANCODE_MEDIA_REWIND = 266, /**< Rewind */ + SDL_SCANCODE_MEDIA_NEXT_TRACK = 267, /**< Next Track */ + SDL_SCANCODE_MEDIA_PREVIOUS_TRACK = 268, /**< Previous Track */ + SDL_SCANCODE_MEDIA_STOP = 269, /**< Stop */ + SDL_SCANCODE_MEDIA_EJECT = 270, /**< Eject */ + SDL_SCANCODE_MEDIA_PLAY_PAUSE = 271, /**< Play / Pause */ + SDL_SCANCODE_MEDIA_SELECT = 272, /* Media Select */ + + SDL_SCANCODE_AC_NEW = 273, /**< AC New */ + SDL_SCANCODE_AC_OPEN = 274, /**< AC Open */ + SDL_SCANCODE_AC_CLOSE = 275, /**< AC Close */ + SDL_SCANCODE_AC_EXIT = 276, /**< AC Exit */ + SDL_SCANCODE_AC_SAVE = 277, /**< AC Save */ + SDL_SCANCODE_AC_PRINT = 278, /**< AC Print */ + SDL_SCANCODE_AC_PROPERTIES = 279, /**< AC Properties */ + + SDL_SCANCODE_AC_SEARCH = 280, /**< AC Search */ + SDL_SCANCODE_AC_HOME = 281, /**< AC Home */ + SDL_SCANCODE_AC_BACK = 282, /**< AC Back */ + SDL_SCANCODE_AC_FORWARD = 283, /**< AC Forward */ + SDL_SCANCODE_AC_STOP = 284, /**< AC Stop */ + SDL_SCANCODE_AC_REFRESH = 285, /**< AC Refresh */ + SDL_SCANCODE_AC_BOOKMARKS = 286, /**< AC Bookmarks */ + + /* @} */ /* Usage page 0x0C */ + + /** + * \name Mobile keys + * + * These are values that are often used on mobile phones. + */ + /* @{ */ + + SDL_SCANCODE_SOFTLEFT = 287, /**< Usually situated below the display on phones and + used as a multi-function feature key for selecting + a software defined function shown on the bottom left + of the display. */ + SDL_SCANCODE_SOFTRIGHT = 288, /**< Usually situated below the display on phones and + used as a multi-function feature key for selecting + a software defined function shown on the bottom right + of the display. */ + SDL_SCANCODE_CALL = 289, /**< Used for accepting phone calls. */ + SDL_SCANCODE_ENDCALL = 290, /**< Used for rejecting phone calls. */ + + /* @} */ /* Mobile keys */ + + /* Add any other keys here. */ + + SDL_SCANCODE_RESERVED = 400, /**< 400-500 reserved for dynamic keycodes */ + + SDL_SCANCODE_COUNT = 512 /**< not a key, just marks the number of scancodes for array bounds */ +}; + +namespace Game +{ + bool GetKey(ScanCode key); +} diff --git a/src/game/Instance.h b/src/game/Instance.h index 7a37e4c..b0ebd17 100644 --- a/src/game/Instance.h +++ b/src/game/Instance.h @@ -1,17 +1,18 @@ #pragma once -#include #include "Level.h" +#include namespace Game { - struct GameInstance - { - bool IsInitialized = false; - uint64_t Size = sizeof(GameInstance); - uint32_t FrameCounter = 0; - int64_t StartTime = 0; - double Now = 0.0; - Level GameLevel; - }; -} + struct GameInstance + { + bool IsInitialized = false; + uint64_t Size = sizeof(GameInstance); + uint32_t FrameCounter = 0; + int64_t StartTime = 0; + double Now = 0.0; + double Delta = 0.0; + Level GameLevel; + }; +} // namespace Game diff --git a/src/game/Level.cpp b/src/game/Level.cpp index 1b3ace4..fa841fe 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -1,85 +1,70 @@ -#include "Level.h" -#include "Log.h" #include "Global.h" #include "Instance.h" +#include "Level.h" +#include "Log.h" #include namespace { - void CreateTransform(float* out, Vec3 pos, Quat rot = {}, Vec3 scale = {1.0f, 1.0f, 1.0f}) - { - if (out == nullptr) return; - float rMat[16]{0}; - float tMat[16]{0}; - float sMat[16]{0}; - bx::mtxFromQuaternion(rMat, bx::Quaternion{rot.X, rot.Y, rot.Z, rot.W}); - bx::mtxTranslate(tMat, pos.X, pos.Y, pos.Z); - bx::mtxScale(sMat, scale.X, scale.Y, scale.Z); - float buf[16]{0}; - bx::mtxMul(buf, rMat, sMat); - bx::mtxMul(out, buf, tMat); - } } namespace Game { - void Level::Setup(GameData& data) - { - Log("Level setup"); - Cubes.Setup(data.EntityStorage); - if (Cubes.Count == 0) - { - for (uint32_t yy = 0; yy < 11; ++yy) - { - for (uint32_t xx = 0; xx < 11; ++xx) - { - Cube* c = Cubes.New(); - if (c) - { - c->TestX = xx; - c->TestY = yy; - } - } - } + void Level::Setup(GameData& data) + { + Log("Level setup"); + Cubes.Setup(data.EntityStorage); + if (Cubes.Count == 0) + { + for (uint32_t yy = 0; yy < 11; ++yy) + { + for (uint32_t xx = 0; xx < 11; ++xx) + { + Cube* c = Cubes.New(); + if (c) + { + c->TestX = xx; + c->TestY = yy; + } + } + } - Cube* floor = Cubes.New(); - } - } + Cube* floor = Cubes.New(); + } + } - void Level::Update() - { - Cubes.Update(); - } + void Level::Update() + { + Cubes.Update(); + } - void Cube::Setup() - { - - } + void Cube::Setup() + { + } - void Cube::Update() - { - if (TestX >= 0 && TestY >= 0) - { - double globalTime = GetInstance().Now; - double time = TestY <= 5 ? globalTime * 1.0f : 0.0f; - if (TestX == 4 && TestY == 4) - { - // bx::mtxTranslate(Transform.M, 0, 0, bx::lerp(-20.0f, -32.0f, bx::sin(globalTime* 0.5f) * 0.5 + 0.5)); - // bx::mtxTranslate(Transform.M, 0, 0, bx::lerp(0.0f, -32.0f, bx::sin(globalTime* 0.5f) * 0.5 + 0.5)); - } - else - { - float scale = 1.0f + TestX * 0.4f; - CreateTransform(Transform.M, - Vec3{TestX * 10.0f - 40.0f, TestY * 10.0f - 40.0f, (float)TestX}, - Quat::FromEuler(time * 10.0f + TestX, time * 5.0f * TestY, 0.0f), - {scale, scale, scale} - ); - } - } - else - { - CreateTransform(Transform.M, {0.0f, -30.0f, 100.0f}, {}, {100.0f, 10.0f, 100.0f}); - } - } -} + void Cube::Update() + { + if (TestX >= 0 && TestY >= 0) + { + double globalTime = GetInstance().Now; + double time = TestY <= 5 ? globalTime * 1.0f : 0.0f; + if (TestX == 4 && TestY == 4) + { + // bx::mtxTranslate(Transform.M, 0, 0, bx::lerp(-20.0f, -32.0f, bx::sin(globalTime* 0.5f) * 0.5 + 0.5)); + // bx::mtxTranslate(Transform.M, 0, 0, bx::lerp(0.0f, -32.0f, bx::sin(globalTime* 0.5f) * 0.5 + 0.5)); + } + else + { + float scale = 1.0f + TestX * 0.4f; + Mat4::CreateTransform(Transform.M, + Vec3{TestX * 10.0f - 40.0f, TestY * 10.0f - 40.0f, (float)TestX}, + Quat::FromEuler(time * 10.0f + TestX, time * 5.0f * TestY, 0.0f), + {scale, scale, scale}); + } + } + else + { + Mat4::CreateTransform(Transform.M, {0.0f, -30.0f, 100.0f}, {}, {100.0f, 10.0f, 100.0f}); + } + } +} // namespace Game diff --git a/src/game/Mesh.cpp b/src/game/Mesh.cpp index c9c4476..a3aba65 100644 --- a/src/game/Mesh.cpp +++ b/src/game/Mesh.cpp @@ -1,5 +1,5 @@ -#include "Mesh.h" #include "Log.h" +#include "Mesh.h" #define TINYGLTF_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION @@ -8,54 +8,54 @@ namespace Game { - void LoadMesh(Model& mesh) - { - mesh.VertLayout.begin() - .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) - .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) - .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float) - .end(); + void LoadMesh(Model& mesh) + { + mesh.VertLayout.begin() + .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) + .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) + .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float) + .end(); - tinygltf::Model model; - tinygltf::TinyGLTF loader; - std::string warn; - std::string err; - bool loadSuccess = loader.LoadASCIIFromFile(&model, &err, &warn, "models/cube.gltf"); + tinygltf::Model model; + tinygltf::TinyGLTF loader; + std::string warn; + std::string err; + bool loadSuccess = loader.LoadASCIIFromFile(&model, &err, &warn, "models/cube.gltf"); - if (!warn.empty()) Log("WARN: %s", warn.c_str()); - if (!err.empty()) Log("ERR: %s", err.c_str()); - if (!loadSuccess) Log("Model load failed!"); + if (!warn.empty()) Log("WARN: %s", warn.c_str()); + if (!err.empty()) Log("ERR: %s", err.c_str()); + if (!loadSuccess) Log("Model load failed!"); - tinygltf::Primitive primitive = model.meshes[0].primitives[0]; - { - tinygltf::Accessor accessor = model.accessors.at(primitive.indices); - tinygltf::BufferView bufferView = model.bufferViews.at(accessor.bufferView); - tinygltf::Buffer buffer = model.buffers[bufferView.buffer]; - const bgfx::Memory* ibMem = bgfx::alloc(bufferView.byteLength); - bx::memCopy(ibMem->data, &buffer.data.at(bufferView.byteOffset), bufferView.byteLength); - mesh.IndexBuffer = bgfx::createIndexBuffer(ibMem); - } - { - tinygltf::Accessor posAccessor = model.accessors.at(primitive.attributes.at("POSITION")); - tinygltf::Accessor uvAccessor = model.accessors.at(primitive.attributes.at("TEXCOORD_0")); - tinygltf::BufferView posBufferView = model.bufferViews[posAccessor.bufferView]; - tinygltf::BufferView uvBufferView = model.bufferViews[uvAccessor.bufferView]; - int posStride = posAccessor.ByteStride(posBufferView); - int uvStride = uvAccessor.ByteStride(uvBufferView); - tinygltf::Buffer posBuffer = model.buffers[posBufferView.buffer]; - tinygltf::Buffer uvBuffer = model.buffers[uvBufferView.buffer]; - - uint32_t vertexCount = posBufferView.byteLength / posStride; - const bgfx::Memory* vbMem = bgfx::alloc(vertexCount * sizeof(PosColorVertex)); - - for (uint32_t i = 0; i < vertexCount; ++i) - { - PosColorVertex& v = *reinterpret_cast(vbMem->data + i * sizeof(PosColorVertex)); - bx::memCopy(&v.x, &posBuffer.data.at(posBufferView.byteOffset + i * posStride), posStride); - v.abgr = 0; - bx::memCopy(&v.uv_x, &uvBuffer.data.at(uvBufferView.byteOffset + i * uvStride), uvStride); - } - mesh.VertexBuffer = bgfx::createVertexBuffer(vbMem, mesh.VertLayout); - } - } -} + tinygltf::Primitive primitive = model.meshes[0].primitives[0]; + { + tinygltf::Accessor accessor = model.accessors.at(primitive.indices); + tinygltf::BufferView bufferView = model.bufferViews.at(accessor.bufferView); + tinygltf::Buffer buffer = model.buffers[bufferView.buffer]; + const bgfx::Memory* ibMem = bgfx::alloc(bufferView.byteLength); + bx::memCopy(ibMem->data, &buffer.data.at(bufferView.byteOffset), bufferView.byteLength); + mesh.IndexBuffer = bgfx::createIndexBuffer(ibMem); + } + { + tinygltf::Accessor posAccessor = model.accessors.at(primitive.attributes.at("POSITION")); + tinygltf::Accessor uvAccessor = model.accessors.at(primitive.attributes.at("TEXCOORD_0")); + tinygltf::BufferView posBufferView = model.bufferViews[posAccessor.bufferView]; + tinygltf::BufferView uvBufferView = model.bufferViews[uvAccessor.bufferView]; + int posStride = posAccessor.ByteStride(posBufferView); + int uvStride = uvAccessor.ByteStride(uvBufferView); + tinygltf::Buffer posBuffer = model.buffers[posBufferView.buffer]; + tinygltf::Buffer uvBuffer = model.buffers[uvBufferView.buffer]; + + uint32_t vertexCount = posBufferView.byteLength / posStride; + const bgfx::Memory* vbMem = bgfx::alloc(vertexCount * sizeof(PosColorVertex)); + + for (uint32_t i = 0; i < vertexCount; ++i) + { + PosColorVertex& v = *reinterpret_cast(vbMem->data + i * sizeof(PosColorVertex)); + bx::memCopy(&v.x, &posBuffer.data.at(posBufferView.byteOffset + i * posStride), posStride); + v.abgr = 0; + bx::memCopy(&v.uv_x, &uvBuffer.data.at(uvBufferView.byteOffset + i * uvStride), uvStride); + } + mesh.VertexBuffer = bgfx::createVertexBuffer(vbMem, mesh.VertLayout); + } + } +} // namespace Game diff --git a/src/game/Setup.cpp b/src/game/Setup.cpp index ad2c260..285a0aa 100644 --- a/src/game/Setup.cpp +++ b/src/game/Setup.cpp @@ -1,65 +1,67 @@ -#include "Setup.h" -#include "Log.h" -#include "bx/timer.h" -#include "rendering/Rendering.h" #include "Global.h" #include "Instance.h" +#include "Log.h" +#include "Setup.h" +#include "bx/timer.h" +#include "rendering/Rendering.h" namespace Game { - class GameSetup - { - public: - GameRendering Rendering; - }; + class GameSetup + { + public: + GameRendering Rendering; + }; - namespace - { - GameSetup SetupInstance; - } + namespace + { + GameSetup SetupInstance; + } - void Setup(SharedData& shared) - { - Log("Game Setup Start!"); + void Setup(SharedData& shared) + { + Log("Game Setup Start!"); - if (shared.Game.PermanentStorage == nullptr) - { - Log("Game memory not initialized!!"); - return; - } - if (shared.Game.EntityStorage == nullptr) - { - Log("Entity memory not initialized!"); - return; - } - if (shared.Game.PermanentStorageSize < sizeof(GameInstance)) - { - Log("Game memory too small! %u < %u", shared.Game.PermanentStorageSize, sizeof(GameInstance)); - return; - } - GameInstance& instance = *reinterpret_cast(shared.Game.PermanentStorage); - if (sizeof(GameInstance) != instance.Size) - { - Log("Game instance size changed, resetting!"); - instance = {}; - } - SetShared(shared); - SetInstance(instance); - SetupInstance.Rendering.Setup(); - instance.GameLevel.Setup(shared.Game); - instance.IsInitialized = true; - } + if (shared.Game.PermanentStorage == nullptr) + { + Log("Game memory not initialized!!"); + return; + } + if (shared.Game.EntityStorage == nullptr) + { + Log("Entity memory not initialized!"); + return; + } + if (shared.Game.PermanentStorageSize < sizeof(GameInstance)) + { + Log("Game memory too small! %u < %u", shared.Game.PermanentStorageSize, sizeof(GameInstance)); + return; + } + GameInstance& instance = *reinterpret_cast(shared.Game.PermanentStorage); + if (sizeof(GameInstance) != instance.Size) + { + Log("Game instance size changed, resetting!"); + instance = {}; + } + SetShared(shared); + SetInstance(instance); + SetupInstance.Rendering.Setup(); + instance.GameLevel.Setup(shared.Game); + instance.IsInitialized = true; + } - void Update() - { - ++GetInstance().FrameCounter; - GetInstance().Now = (bx::getHPCounter() - GetInstance().StartTime) / (double)(bx::getHPFrequency()); - SetupInstance.Rendering.Update(); - } + void Update() + { + ++GetInstance().FrameCounter; + double newNow = (bx::getHPCounter() - GetInstance().StartTime) / (double)(bx::getHPFrequency()); + GetInstance().Delta = newNow - GetInstance().Now; + GetInstance().Now = newNow; + SetupInstance.Rendering.Update(); + } - void Shutdown() - { - Log("Shutdown"); - SetupInstance.Rendering.Shutdown(); - } -} + void Shutdown() + { + Log("Shutdown"); + SetupInstance.Rendering.Shutdown(); + } +} // namespace Game diff --git a/src/game/compiled-shaders/dx11/frag.bin b/src/game/compiled-shaders/dx11/frag.bin index 07ddd9b..627c200 100644 Binary files a/src/game/compiled-shaders/dx11/frag.bin and b/src/game/compiled-shaders/dx11/frag.bin differ diff --git a/src/game/compiled-shaders/glsl/frag.bin b/src/game/compiled-shaders/glsl/frag.bin index 9d01cab..48b43e2 100644 Binary files a/src/game/compiled-shaders/glsl/frag.bin and b/src/game/compiled-shaders/glsl/frag.bin differ diff --git a/src/game/compiled-shaders/spirv/frag.bin b/src/game/compiled-shaders/spirv/frag.bin index b3fbd8d..6f7c44f 100644 Binary files a/src/game/compiled-shaders/spirv/frag.bin and b/src/game/compiled-shaders/spirv/frag.bin differ diff --git a/src/game/rendering/Rendering.cpp b/src/game/rendering/Rendering.cpp index e7aa717..d968888 100644 --- a/src/game/rendering/Rendering.cpp +++ b/src/game/rendering/Rendering.cpp @@ -1,215 +1,239 @@ -#include "Rendering.h" -#include "../Log.h" #include "../../engine/Shared.h" #include "../Global.h" +#include "../Input.h" #include "../Instance.h" +#include "../Log.h" #include "../Mesh.h" +#include "Rendering.h" #include "bgfx/defines.h" #include "bx/timer.h" -#include #include +#include #include using namespace std::chrono_literals; namespace Game { - namespace - { - static const bgfx::Memory* loadMem(bx::FileReaderI* _reader, const bx::FilePath& _filePath) - { - if (bx::open(_reader, _filePath)) - { - uint32_t size = (uint32_t)bx::getSize(_reader); - const bgfx::Memory* mem = bgfx::alloc(size + 1); - bx::read(_reader, mem->data, size, bx::ErrorAssert{}); - bx::close(_reader); - mem->data[mem->size - 1] = '\0'; - return mem; - } + namespace + { + static const bgfx::Memory* loadMem(bx::FileReaderI* _reader, const bx::FilePath& _filePath) + { + if (bx::open(_reader, _filePath)) + { + uint32_t size = (uint32_t)bx::getSize(_reader); + const bgfx::Memory* mem = bgfx::alloc(size + 1); + bx::read(_reader, mem->data, size, bx::ErrorAssert{}); + bx::close(_reader); + mem->data[mem->size - 1] = '\0'; + return mem; + } - Log("Failed to load %s.", _filePath.getCPtr()); - return NULL; - } + Log("Failed to load %s.", _filePath.getCPtr()); + return NULL; + } - bgfx::ShaderHandle loadShader(const char* FILENAME) - { - const char* shaderPath = "???"; + bgfx::ShaderHandle loadShader(const char* FILENAME) + { + const char* shaderPath = "???"; - switch (bgfx::getRendererType()) { - case bgfx::RendererType::Agc: - case bgfx::RendererType::Nvn: - case bgfx::RendererType::Count: - case bgfx::RendererType::Noop: break; - case bgfx::RendererType::Direct3D11: - case bgfx::RendererType::Direct3D12: shaderPath = "game/compiled-shaders/dx11/"; break; - case bgfx::RendererType::Gnm: shaderPath = "game/compiled-shaders/pssl/"; break; - case bgfx::RendererType::Metal: shaderPath = "game/compiled-shaders/metal/"; break; - case bgfx::RendererType::OpenGL: shaderPath = "game/compiled-shaders/glsl/"; break; - case bgfx::RendererType::OpenGLES: shaderPath = "game/compiled-shaders/essl/"; break; - case bgfx::RendererType::Vulkan: shaderPath = "game/compiled-shaders/spirv/"; break; - } + switch (bgfx::getRendererType()) + { + case bgfx::RendererType::Agc: + case bgfx::RendererType::Nvn: + case bgfx::RendererType::Count: + case bgfx::RendererType::Noop: + break; + case bgfx::RendererType::Direct3D11: + case bgfx::RendererType::Direct3D12: + shaderPath = "game/compiled-shaders/dx11/"; + break; + case bgfx::RendererType::Gnm: + shaderPath = "game/compiled-shaders/pssl/"; + break; + case bgfx::RendererType::Metal: + shaderPath = "game/compiled-shaders/metal/"; + break; + case bgfx::RendererType::OpenGL: + shaderPath = "game/compiled-shaders/glsl/"; + break; + case bgfx::RendererType::OpenGLES: + shaderPath = "game/compiled-shaders/essl/"; + break; + case bgfx::RendererType::Vulkan: + shaderPath = "game/compiled-shaders/spirv/"; + break; + } - char buffer[512]{ 0 }; - bx::strCopy(buffer, sizeof(buffer), shaderPath); - bx::strCat(buffer, sizeof(buffer), FILENAME); - bx::strCat(buffer, sizeof(buffer), ".bin"); + char buffer[512]{0}; + bx::strCopy(buffer, sizeof(buffer), shaderPath); + bx::strCat(buffer, sizeof(buffer), FILENAME); + bx::strCat(buffer, sizeof(buffer), ".bin"); - Log("Loading shader at %s", buffer); + Log("Loading shader at %s", buffer); - FILE* file; - for (int32_t i = 0; i < 3; ++i) - { - file = fopen(buffer, "rb"); - if (file == nullptr) - { - std::this_thread::sleep_for(100ms); - break; - } - - fseek(file, 0, SEEK_END); - long fileSize = ftell(file); - fseek(file, 0, SEEK_SET); + FILE* file; + for (int32_t i = 0; i < 3; ++i) + { + file = fopen(buffer, "rb"); + if (file == nullptr) + { + std::this_thread::sleep_for(100ms); + break; + } - const bgfx::Memory* mem = bgfx::alloc(fileSize + 1); - fread(mem->data, 1, fileSize, file); - mem->data[mem->size - 1] = '\0'; - fclose(file); + fseek(file, 0, SEEK_END); + long fileSize = ftell(file); + fseek(file, 0, SEEK_SET); - return bgfx::createShader(mem); - } - - Log("Failed to load shader %s", FILENAME); - return {}; - } - } + const bgfx::Memory* mem = bgfx::alloc(fileSize + 1); + fread(mem->data, 1, fileSize, file); + mem->data[mem->size - 1] = '\0'; + fclose(file); - void GameRendering::Setup() - { - Log("Game rendering setup..."); - SharedData& shared = GetShared(); - - bgfx::Init init; - init.type = bgfx::RendererType::Direct3D12; - init.debug = true; - init.callback = &Callback; - init.platformData.nwh = shared.Window.Handle; - init.platformData.ndt = nullptr; - init.platformData.type = bgfx::NativeWindowHandleType::Default; - init.resolution.width = shared.Window.WindowWidth; - init.resolution.height = shared.Window.WindowHeight; - init.resolution.reset = BGFX_RESET_VSYNC; + return bgfx::createShader(mem); + } - Log("%i by %i", init.resolution.width, init.resolution.height); - - if (!bgfx::init(init)) - { - Log("BGFX setup failed!"); - } - else - { - Log("BGFX setup succeded!"); - } - bgfx::setDebug(BGFX_DEBUG_TEXT); - bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x303030ff, 1.0f, 0); + Log("Failed to load shader %s", FILENAME); + return {}; + } + } // namespace - LoadMesh(Models[0]); - - bgfx::ShaderHandle vertexShader = loadShader("vert"); - bgfx::ShaderHandle fragmentShader = loadShader("frag"); - - Materials[0].Shader = bgfx::createProgram(vertexShader, fragmentShader, true); - Materials[0].State = 0 - | BGFX_STATE_WRITE_RGB - | BGFX_STATE_WRITE_A - | BGFX_STATE_WRITE_Z - | BGFX_STATE_DEPTH_TEST_LESS - | BGFX_STATE_CULL_CCW - | BGFX_STATE_MSAA; - Materials[0].Uniforms[Material::UniformTimeIdx] = bgfx::createUniform("u_time", bgfx::UniformType::Vec4); - - if (!GetInstance().IsInitialized) - { - GetInstance().StartTime = bx::getHPCounter(); - } - } + void GameRendering::Setup() + { + Log("Game rendering setup..."); + SharedData& shared = GetShared(); - void GameRendering::Update() - { - SharedData& shared = GetShared(); + bgfx::Init init; + init.type = bgfx::RendererType::Direct3D12; + init.debug = true; + init.callback = &Callback; + init.platformData.nwh = shared.Window.Handle; + init.platformData.ndt = nullptr; + init.platformData.type = bgfx::NativeWindowHandleType::Default; + init.resolution.width = shared.Window.WindowWidth; + init.resolution.height = shared.Window.WindowHeight; + init.resolution.reset = BGFX_RESET_VSYNC; - // Reload shaders if necessary - FileChangeNotification* shaderChange = nullptr; - if (shared.Dev.ChangedShaderCount > 0) - { - shared.Dev.ChangedShaderCount = 0; - - // TODO: when to destroy shader? - // bgfx::destroy(Shader); - bgfx::ShaderHandle vertexShader = loadShader("vert"); - bgfx::ShaderHandle fragmentShader = loadShader("frag"); - if (isValid(vertexShader) && isValid(fragmentShader)) - { - bgfx::ProgramHandle newProgram = bgfx::createProgram(vertexShader, fragmentShader, true); - if (isValid(newProgram)) - { - Materials[0].Shader = newProgram; - } - else - { - Log("Failed to load shader!"); - } - } - } + Log("%i by %i", init.resolution.width, init.resolution.height); - GetInstance().GameLevel.Update(); - - const bx::Vec3 at = { 0.0f, 0.0f, 0.0f }; - const bx::Vec3 eye = { 0.0f, 0.0f, -35.0f }; + if (!bgfx::init(init)) + { + Log("BGFX setup failed!"); + } + else + { + Log("BGFX setup succeded!"); + } + bgfx::setDebug(BGFX_DEBUG_TEXT); + bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x303030ff, 1.0f, 0); - // Set view and projection matrix for view 0. - { - float view[16]; - bx::mtxLookAt(view, eye, at); + LoadMesh(Models[0]); - float proj[16]; - bx::mtxProj(proj, 75.0f, float(shared.Window.WindowWidth) / float(shared.Window.WindowHeight), 0.1f, 1000.0f, bgfx::getCaps()->homogeneousDepth); - bgfx::setViewTransform(0, view, proj); + bgfx::ShaderHandle vertexShader = loadShader("vert"); + bgfx::ShaderHandle fragmentShader = loadShader("frag"); - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, shared.Window.WindowWidth, shared.Window.WindowHeight); - } + Materials[0].Shader = bgfx::createProgram(vertexShader, fragmentShader, true); + Materials[0].State = 0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_WRITE_Z | + BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_CULL_CCW | BGFX_STATE_MSAA; + Materials[0].Uniforms[Material::UniformTimeIdx] = bgfx::createUniform("u_time", bgfx::UniformType::Vec4); - float TimeValues[4]{0.0f}; - TimeValues[0] = GetInstance().Now; + if (!GetInstance().IsInitialized) + { + GetInstance().StartTime = bx::getHPCounter(); + } + } - for (int32_t i = 0; i < GetInstance().GameLevel.Cubes.Count; ++i) - { - Cube* c = GetInstance().GameLevel.Cubes.Get(i); - if (c) - { - bgfx::setTransform(c->Transform.M); + void GameRendering::Update() + { + SharedData& shared = GetShared(); - Model& currentModel = Models[c->ModelIdx]; - Material& currentMaterial = Materials[c->MaterialIdx]; - bgfx::setVertexBuffer(0, currentModel.VertexBuffer); - bgfx::setIndexBuffer(currentModel.IndexBuffer); - bgfx::setState(currentMaterial.State); - bgfx::setUniform(Materials[0].Uniforms[Material::UniformTimeIdx], TimeValues); + // Reload shaders if necessary + FileChangeNotification* shaderChange = nullptr; + if (shared.Dev.ChangedShaderCount > 0) + { + shared.Dev.ChangedShaderCount = 0; - // Submit primitive for rendering to view 0. - bgfx::submit(0, currentMaterial.Shader); - } - } + // TODO: when to destroy shader? + // bgfx::destroy(Shader); + bgfx::ShaderHandle vertexShader = loadShader("vert"); + bgfx::ShaderHandle fragmentShader = loadShader("frag"); + if (isValid(vertexShader) && isValid(fragmentShader)) + { + bgfx::ProgramHandle newProgram = bgfx::createProgram(vertexShader, fragmentShader, true); + if (isValid(newProgram)) + { + Materials[0].Shader = newProgram; + } + else + { + Log("Failed to load shader!"); + } + } + } - bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.1f", GetInstance().Now); - bgfx::dbgTextPrintf(1, 2, 0x0f, "Frame: %u", GetInstance().FrameCounter); + { + GetInstance().GameLevel.Update(); + float forwardInput = + (GetKey(ScanCode::SDL_SCANCODE_W) ? 1.0f : 0.0f) + (GetKey(ScanCode::SDL_SCANCODE_S) ? -1.0f : 0.0f); + float rightInput = + (GetKey(ScanCode::SDL_SCANCODE_D) ? 1.0f : 0.0f) + (GetKey(ScanCode::SDL_SCANCODE_A) ? -1.0f : 0.0f); + Vec3 inputVec = {rightInput, 0.0f, forwardInput}; - bgfx::frame(); - } + Vec3 camForward = Cam.Transform.Forward(); + Vec3 camRight = Cam.Transform.Right(); - void GameRendering::Shutdown() - { - bgfx::shutdown(); - } -} + Cam.Transform.Translate( + {camForward.X * forwardInput, camForward.Y * forwardInput, camForward.Z * forwardInput}); + Cam.Transform.Translate({camRight.X * rightInput, camRight.Y * rightInput, camRight.Z * rightInput}); + } + + // Set view and projection matrix for view 0. + { + float proj[16]; + bx::mtxProj(proj, + 75.0f, + float(shared.Window.WindowWidth) / float(shared.Window.WindowHeight), + 0.1f, + 1000.0f, + bgfx::getCaps()->homogeneousDepth); + bgfx::setViewTransform(0, Cam.Transform.M, proj); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, shared.Window.WindowWidth, shared.Window.WindowHeight); + } + + float TimeValues[4]{0.0f}; + TimeValues[0] = GetInstance().Now; + + for (int32_t i = 0; i < GetInstance().GameLevel.Cubes.Count; ++i) + { + Cube* c = GetInstance().GameLevel.Cubes.Get(i); + if (c) + { + bgfx::setTransform(c->Transform.M); + + Model& currentModel = Models[c->ModelIdx]; + Material& currentMaterial = Materials[c->MaterialIdx]; + bgfx::setVertexBuffer(0, currentModel.VertexBuffer); + bgfx::setIndexBuffer(currentModel.IndexBuffer); + bgfx::setState(currentMaterial.State); + bgfx::setUniform(Materials[0].Uniforms[Material::UniformTimeIdx], TimeValues); + + // Submit primitive for rendering to view 0. + bgfx::submit(0, currentMaterial.Shader); + } + } + + bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.1f", GetInstance().Now); + bgfx::dbgTextPrintf(1, 2, 0x0F, "Frame: %u", GetInstance().FrameCounter); + bgfx::dbgTextPrintf(1, 3, 0x0F, "Delta: %.3fms / %.0ffps", GetInstance().Delta, 1.0 / GetInstance().Delta); + + bgfx::frame(); + } + + void GameRendering::Shutdown() + { + bgfx::shutdown(); + } +} // namespace Game diff --git a/src/game/rendering/Rendering.h b/src/game/rendering/Rendering.h index c159b31..0692427 100644 --- a/src/game/rendering/Rendering.h +++ b/src/game/rendering/Rendering.h @@ -1,108 +1,132 @@ #pragma once +#include "../Global.h" #include #include #include namespace Game { - struct PosColorVertex - { - float x; - float y; - float z; - uint32_t abgr; - float uv_x; - float uv_y; - }; + struct PosColorVertex + { + float x; + float y; + float z; + uint32_t abgr; + float uv_x; + float uv_y; + }; - struct BgfxCallback : public bgfx::CallbackI - { - virtual ~BgfxCallback() - { - } + struct BgfxCallback : public bgfx::CallbackI + { + virtual ~BgfxCallback() + { + } - virtual void fatal(const char* _filePath, uint16_t _line, bgfx::Fatal::Enum _code, const char* _str) override - { - // Something unexpected happened, inform user and bail out. - printf("Fatal error: 0x%08x: %s", _code, _str); + virtual void fatal(const char* _filePath, uint16_t _line, bgfx::Fatal::Enum _code, const char* _str) override + { + // Something unexpected happened, inform user and bail out. + printf("Fatal error: 0x%08x: %s", _code, _str); - // Must terminate, continuing will cause crash anyway. - abort(); - } + // Must terminate, continuing will cause crash anyway. + abort(); + } - virtual void traceVargs(const char* _filePath, uint16_t _line, const char* _format, va_list _argList) override - { - printf("%s (%d): ", _filePath, _line); - vprintf(_format, _argList); - } + virtual void traceVargs(const char* _filePath, uint16_t _line, const char* _format, va_list _argList) override + { + printf("%s (%d): ", _filePath, _line); + vprintf(_format, _argList); + } - virtual void profilerBegin(const char* /*_name*/, uint32_t /*_abgr*/, const char* /*_filePath*/, uint16_t /*_line*/) override - { - } + virtual void profilerBegin(const char* /*_name*/, + uint32_t /*_abgr*/, + const char* /*_filePath*/, + uint16_t /*_line*/) override + { + } - virtual void profilerBeginLiteral(const char* /*_name*/, uint32_t /*_abgr*/, const char* /*_filePath*/, uint16_t /*_line*/) override - { - } + virtual void profilerBeginLiteral(const char* /*_name*/, + uint32_t /*_abgr*/, + const char* /*_filePath*/, + uint16_t /*_line*/) override + { + } - virtual void profilerEnd() override - { - } + virtual void profilerEnd() override + { + } - virtual uint32_t cacheReadSize(uint64_t _id) override - { - return 0; - } + virtual uint32_t cacheReadSize(uint64_t _id) override + { + return 0; + } - virtual bool cacheRead(uint64_t _id, void* _data, uint32_t _size) override - { - return false; - } + virtual bool cacheRead(uint64_t _id, void* _data, uint32_t _size) override + { + return false; + } - virtual void cacheWrite(uint64_t _id, const void* _data, uint32_t _size) override - { - } + virtual void cacheWrite(uint64_t _id, const void* _data, uint32_t _size) override + { + } - virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t /*_size*/, bool _yflip) override - { - } + virtual void screenShot(const char* _filePath, + uint32_t _width, + uint32_t _height, + uint32_t _pitch, + const void* _data, + uint32_t /*_size*/, + bool _yflip) override + { + } - virtual void captureBegin(uint32_t _width, uint32_t _height, uint32_t /*_pitch*/, bgfx::TextureFormat::Enum /*_format*/, bool _yflip) override - { - } + virtual void captureBegin(uint32_t _width, + uint32_t _height, + uint32_t /*_pitch*/, + bgfx::TextureFormat::Enum /*_format*/, + bool _yflip) override + { + } - virtual void captureEnd() override - { - } + virtual void captureEnd() override + { + } - virtual void captureFrame(const void* _data, uint32_t /*_size*/) override - { - } - }; + virtual void captureFrame(const void* _data, uint32_t /*_size*/) override + { + } + }; - struct Model - { - bgfx::VertexBufferHandle VertexBuffer; - bgfx::IndexBufferHandle IndexBuffer; - bgfx::VertexLayout VertLayout; - }; - - struct Material - { - static constexpr uint32_t UniformTimeIdx = 0; - bgfx::ProgramHandle Shader; - bgfx::UniformHandle Uniforms[8]; - uint64_t State = 0; - }; + struct Model + { + bgfx::VertexBufferHandle VertexBuffer; + bgfx::IndexBufferHandle IndexBuffer; + bgfx::VertexLayout VertLayout; + }; - class GameRendering - { - private: - Material Materials[8]; - Model Models[8]; - BgfxCallback Callback; - public: - void Setup(); - void Update(); - void Shutdown(); - }; -} + struct Material + { + static constexpr uint32_t UniformTimeIdx = 0; + bgfx::ProgramHandle Shader; + bgfx::UniformHandle Uniforms[8]; + uint64_t State = 0; + }; + + struct Camera + { + Mat4 Transform; + }; + + class GameRendering + { + private: + Material Materials[8]; + Model Models[8]; + BgfxCallback Callback; + Camera Cam; + + public: + void Setup(); + void Update(); + void Shutdown(); + }; +} // namespace Game diff --git a/src/game/shaders/frag.sc b/src/game/shaders/frag.sc index 23cd5fb..0cf41bf 100644 --- a/src/game/shaders/frag.sc +++ b/src/game/shaders/frag.sc @@ -70,5 +70,6 @@ void main() float patternFractional = spacingLog - patternScaleLevel; vec2 uv = v_uv0 * exp2(patternScaleLevel); - gl_FragColor = circles(uv, patternScaleLevel, patternFractional, brightness); + float dither = circles(uv, patternScaleLevel, patternFractional, brightness); + gl_FragColor = lerp(dither, vec4(0.1, 0.1, 0.15, 1.0), vec4(0.9, 0.75, 0.3, 1.0)); }