camera movement & formatting

This commit is contained in:
Asuro
2025-02-12 01:24:28 +01:00
parent bf2371eca0
commit 03aecb6d44
18 changed files with 1316 additions and 574 deletions

View File

@@ -1,3 +1,9 @@
BasedOnStyle: Microsoft BasedOnStyle: Microsoft
IndentWidth: 4 IndentWidth: 4
NamespaceIndentation: NI_All NamespaceIndentation: All
PointerAlignment: Left
AllowShortIfStatementsOnASingleLine: WithoutElse
BreakBeforeBraces: Allman
BinPackParameters: false
BinPackArguments: false

View File

@@ -6,6 +6,7 @@ struct SharedWindowData
void* Handle = nullptr; void* Handle = nullptr;
int32_t WindowWidth = 1920; int32_t WindowWidth = 1920;
int32_t WindowHeight = 1080; int32_t WindowHeight = 1080;
bool HeldScanCodes[512]{0};
}; };
struct FileChangeNotification struct FileChangeNotification
@@ -38,4 +39,3 @@ struct SharedData
typedef void (*Startup)(SharedData& shared); typedef void (*Startup)(SharedData& shared);
typedef void (*Update)(); typedef void (*Update)();
typedef void (*Shutdown)(); typedef void (*Shutdown)();

View File

@@ -1,8 +1,8 @@
#include "Window.h"
#include "SDL3/SDL_events.h" #include "SDL3/SDL_events.h"
#include "Shared.h" #include "Shared.h"
#include <cstdio> #include "Window.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <cstdio>
void EngineWindow::Startup(SharedWindowData& shared) void EngineWindow::Startup(SharedWindowData& shared)
{ {
@@ -18,20 +18,17 @@ void EngineWindow::Startup(SharedWindowData& shared)
return; return;
} }
auto props = SDL_GetWindowProperties(Window); auto props = SDL_GetWindowProperties(Window);
SDL_EnumerateProperties(props, [](void*, SDL_PropertiesID id, const char* name) SDL_EnumerateProperties(
{ props, [](void*, SDL_PropertiesID id, const char* name) { printf("Prop: %s\n", name); }, nullptr);
printf("Prop: %s\n", name);
}, nullptr);
shared.Handle = SDL_GetPointerProperty(props, "SDL.window.win32.hwnd", nullptr); shared.Handle = SDL_GetPointerProperty(props, "SDL.window.win32.hwnd", nullptr);
if (shared.Handle == nullptr) if (shared.Handle == nullptr)
{ {
printf("Failed to get window pointer!\n"); printf("Failed to get window pointer!\n");
return; return;
} }
} }
void EngineWindow::Update(SharedWindowData& Shared) void EngineWindow::Update(SharedWindowData& shared)
{ {
SDL_Event evt; SDL_Event evt;
while (SDL_PollEvent(&evt)) while (SDL_PollEvent(&evt))
@@ -40,7 +37,7 @@ void EngineWindow::Update(SharedWindowData& Shared)
{ {
case SDL_EVENT_WINDOW_RESIZED: case SDL_EVENT_WINDOW_RESIZED:
{ {
SDL_GetWindowSize(Window, &Shared.WindowWidth, &Shared.WindowHeight); SDL_GetWindowSize(Window, &shared.WindowWidth, &shared.WindowHeight);
break; break;
} }
case SDL_EVENT_WINDOW_CLOSE_REQUESTED: case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
@@ -48,6 +45,21 @@ void EngineWindow::Update(SharedWindowData& Shared)
CloseRequested = true; CloseRequested = true;
break; 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;
} }
} }
} }

236
src/engine/test.txt Normal file
View File

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

View File

@@ -7,7 +7,7 @@ namespace
{ {
SharedData* SharedInstance = nullptr; SharedData* SharedInstance = nullptr;
Game::GameInstance* GameInst = nullptr; Game::GameInstance* GameInst = nullptr;
} } // namespace
Quat Quat::FromEuler(float x, float y, float z) Quat Quat::FromEuler(float x, float y, float z)
{ {
@@ -22,8 +22,7 @@ Quat Quat::FromEuler(float x, float y, float z)
float sY = bx::sin(y); float sY = bx::sin(y);
float sZ = bx::sin(z); float sZ = bx::sin(z);
return Quat{ return Quat{cX * cY * cZ - sX * sY * sZ,
cX * cY * cZ - sX * sY * sZ,
sY * cX * cZ - sX * sZ * cY, sY * cX * cZ - sX * sZ * cY,
sX * sY * cZ + sZ * cX * cY, sX * sY * cZ + sZ * cX * cY,
sX * cY * cZ + sY * sZ * cX}; sX * cY * cZ + sY * sZ * cX};
@@ -34,6 +33,42 @@ 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 namespace Game
{ {
SharedData& GetShared() SharedData& GetShared()
@@ -57,4 +92,4 @@ namespace Game
{ {
GameInst = &instance; GameInst = &instance;
} }
} } // namespace Game

View File

@@ -1,4 +1,5 @@
#pragma once #pragma once
#include <bx/math.h>
#include <cstdint> #include <cstdint>
struct SharedData; struct SharedData;
@@ -26,6 +27,11 @@ struct Vec3
float X = 0.0f; float X = 0.0f;
float Y = 0.0f; float Y = 0.0f;
float Z = 0.0f; float Z = 0.0f;
bx::Vec3 ToBX()
{
return {X, Y, Z};
};
}; };
struct Quat struct Quat
@@ -42,11 +48,29 @@ struct Quat
struct Mat4 struct Mat4
{ {
float M[16]{ float M[16]{
1.0, 0.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 0.0, 1.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 namespace Game
@@ -57,4 +81,4 @@ namespace Game
void SetShared(SharedData& instance); void SetShared(SharedData& instance);
GameInstance& GetInstance(); GameInstance& GetInstance();
void SetInstance(GameInstance& instance); void SetInstance(GameInstance& instance);
} } // namespace Game

11
src/game/Input.cpp Normal file
View File

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

381
src/game/Input.h Normal file
View File

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

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <cstdint>
#include "Level.h" #include "Level.h"
#include <cstdint>
namespace Game namespace Game
{ {
@@ -12,6 +12,7 @@ namespace Game
uint32_t FrameCounter = 0; uint32_t FrameCounter = 0;
int64_t StartTime = 0; int64_t StartTime = 0;
double Now = 0.0; double Now = 0.0;
double Delta = 0.0;
Level GameLevel; Level GameLevel;
}; };
} } // namespace Game

View File

@@ -1,24 +1,11 @@
#include "Level.h"
#include "Log.h"
#include "Global.h" #include "Global.h"
#include "Instance.h" #include "Instance.h"
#include "Level.h"
#include "Log.h"
#include <bx/math.h> #include <bx/math.h>
namespace 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 namespace Game
@@ -53,7 +40,6 @@ namespace Game
void Cube::Setup() void Cube::Setup()
{ {
} }
void Cube::Update() void Cube::Update()
@@ -70,16 +56,15 @@ namespace Game
else else
{ {
float scale = 1.0f + TestX * 0.4f; float scale = 1.0f + TestX * 0.4f;
CreateTransform(Transform.M, Mat4::CreateTransform(Transform.M,
Vec3{TestX * 10.0f - 40.0f, TestY * 10.0f - 40.0f, (float)TestX}, 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), Quat::FromEuler(time * 10.0f + TestX, time * 5.0f * TestY, 0.0f),
{scale, scale, scale} {scale, scale, scale});
);
} }
} }
else else
{ {
CreateTransform(Transform.M, {0.0f, -30.0f, 100.0f}, {}, {100.0f, 10.0f, 100.0f}); Mat4::CreateTransform(Transform.M, {0.0f, -30.0f, 100.0f}, {}, {100.0f, 10.0f, 100.0f});
}
} }
} }
} // namespace Game

View File

@@ -1,5 +1,5 @@
#include "Mesh.h"
#include "Log.h" #include "Log.h"
#include "Mesh.h"
#define TINYGLTF_IMPLEMENTATION #define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
@@ -58,4 +58,4 @@ namespace Game
mesh.VertexBuffer = bgfx::createVertexBuffer(vbMem, mesh.VertLayout); mesh.VertexBuffer = bgfx::createVertexBuffer(vbMem, mesh.VertLayout);
} }
} }
} } // namespace Game

View File

@@ -1,9 +1,9 @@
#include "Setup.h"
#include "Log.h"
#include "bx/timer.h"
#include "rendering/Rendering.h"
#include "Global.h" #include "Global.h"
#include "Instance.h" #include "Instance.h"
#include "Log.h"
#include "Setup.h"
#include "bx/timer.h"
#include "rendering/Rendering.h"
namespace Game namespace Game
{ {
@@ -53,7 +53,9 @@ namespace Game
void Update() void Update()
{ {
++GetInstance().FrameCounter; ++GetInstance().FrameCounter;
GetInstance().Now = (bx::getHPCounter() - GetInstance().StartTime) / (double)(bx::getHPFrequency()); double newNow = (bx::getHPCounter() - GetInstance().StartTime) / (double)(bx::getHPFrequency());
GetInstance().Delta = newNow - GetInstance().Now;
GetInstance().Now = newNow;
SetupInstance.Rendering.Update(); SetupInstance.Rendering.Update();
} }
@@ -62,4 +64,4 @@ namespace Game
Log("Shutdown"); Log("Shutdown");
SetupInstance.Rendering.Shutdown(); SetupInstance.Rendering.Shutdown();
} }
} } // namespace Game

View File

@@ -1,13 +1,14 @@
#include "Rendering.h"
#include "../Log.h"
#include "../../engine/Shared.h" #include "../../engine/Shared.h"
#include "../Global.h" #include "../Global.h"
#include "../Input.h"
#include "../Instance.h" #include "../Instance.h"
#include "../Log.h"
#include "../Mesh.h" #include "../Mesh.h"
#include "Rendering.h"
#include "bgfx/defines.h" #include "bgfx/defines.h"
#include "bx/timer.h" #include "bx/timer.h"
#include <bx/file.h>
#include <bgfx/bgfx.h> #include <bgfx/bgfx.h>
#include <bx/file.h>
#include <thread> #include <thread>
using namespace std::chrono_literals; using namespace std::chrono_literals;
@@ -36,18 +37,32 @@ namespace Game
{ {
const char* shaderPath = "???"; const char* shaderPath = "???";
switch (bgfx::getRendererType()) { switch (bgfx::getRendererType())
{
case bgfx::RendererType::Agc: case bgfx::RendererType::Agc:
case bgfx::RendererType::Nvn: case bgfx::RendererType::Nvn:
case bgfx::RendererType::Count: case bgfx::RendererType::Count:
case bgfx::RendererType::Noop: break; case bgfx::RendererType::Noop:
break;
case bgfx::RendererType::Direct3D11: case bgfx::RendererType::Direct3D11:
case bgfx::RendererType::Direct3D12: shaderPath = "game/compiled-shaders/dx11/"; break; case bgfx::RendererType::Direct3D12:
case bgfx::RendererType::Gnm: shaderPath = "game/compiled-shaders/pssl/"; break; shaderPath = "game/compiled-shaders/dx11/";
case bgfx::RendererType::Metal: shaderPath = "game/compiled-shaders/metal/"; break; break;
case bgfx::RendererType::OpenGL: shaderPath = "game/compiled-shaders/glsl/"; break; case bgfx::RendererType::Gnm:
case bgfx::RendererType::OpenGLES: shaderPath = "game/compiled-shaders/essl/"; break; shaderPath = "game/compiled-shaders/pssl/";
case bgfx::RendererType::Vulkan: shaderPath = "game/compiled-shaders/spirv/"; break; 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}; char buffer[512]{0};
@@ -82,7 +97,7 @@ namespace Game
Log("Failed to load shader %s", FILENAME); Log("Failed to load shader %s", FILENAME);
return {}; return {};
} }
} } // namespace
void GameRendering::Setup() void GameRendering::Setup()
{ {
@@ -119,13 +134,8 @@ namespace Game
bgfx::ShaderHandle fragmentShader = loadShader("frag"); bgfx::ShaderHandle fragmentShader = loadShader("frag");
Materials[0].Shader = bgfx::createProgram(vertexShader, fragmentShader, true); Materials[0].Shader = bgfx::createProgram(vertexShader, fragmentShader, true);
Materials[0].State = 0 Materials[0].State = 0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_WRITE_Z |
| BGFX_STATE_WRITE_RGB BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_CULL_CCW | BGFX_STATE_MSAA;
| 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); Materials[0].Uniforms[Material::UniformTimeIdx] = bgfx::createUniform("u_time", bgfx::UniformType::Vec4);
if (!GetInstance().IsInitialized) if (!GetInstance().IsInitialized)
@@ -162,19 +172,32 @@ namespace Game
} }
} }
{
GetInstance().GameLevel.Update(); 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};
const bx::Vec3 at = { 0.0f, 0.0f, 0.0f }; Vec3 camForward = Cam.Transform.Forward();
const bx::Vec3 eye = { 0.0f, 0.0f, -35.0f }; Vec3 camRight = Cam.Transform.Right();
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. // Set view and projection matrix for view 0.
{ {
float view[16];
bx::mtxLookAt(view, eye, at);
float proj[16]; float proj[16];
bx::mtxProj(proj, 75.0f, float(shared.Window.WindowWidth) / float(shared.Window.WindowHeight), 0.1f, 1000.0f, bgfx::getCaps()->homogeneousDepth); bx::mtxProj(proj,
bgfx::setViewTransform(0, view, 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. // Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, shared.Window.WindowWidth, shared.Window.WindowHeight); bgfx::setViewRect(0, 0, 0, shared.Window.WindowWidth, shared.Window.WindowHeight);
@@ -203,7 +226,8 @@ namespace Game
} }
bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.1f", GetInstance().Now); bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.1f", GetInstance().Now);
bgfx::dbgTextPrintf(1, 2, 0x0f, "Frame: %u", GetInstance().FrameCounter); 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(); bgfx::frame();
} }
@@ -212,4 +236,4 @@ namespace Game
{ {
bgfx::shutdown(); bgfx::shutdown();
} }
} } // namespace Game

View File

@@ -1,4 +1,5 @@
#pragma once #pragma once
#include "../Global.h"
#include <bgfx/bgfx.h> #include <bgfx/bgfx.h>
#include <bx/string.h> #include <bx/string.h>
#include <cstdio> #include <cstdio>
@@ -36,11 +37,17 @@ namespace Game
vprintf(_format, _argList); 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
{ {
} }
@@ -62,11 +69,21 @@ namespace Game
{ {
} }
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
{ {
} }
@@ -94,15 +111,22 @@ namespace Game
uint64_t State = 0; uint64_t State = 0;
}; };
struct Camera
{
Mat4 Transform;
};
class GameRendering class GameRendering
{ {
private: private:
Material Materials[8]; Material Materials[8];
Model Models[8]; Model Models[8];
BgfxCallback Callback; BgfxCallback Callback;
Camera Cam;
public: public:
void Setup(); void Setup();
void Update(); void Update();
void Shutdown(); void Shutdown();
}; };
} } // namespace Game

View File

@@ -70,5 +70,6 @@ void main()
float patternFractional = spacingLog - patternScaleLevel; float patternFractional = spacingLog - patternScaleLevel;
vec2 uv = v_uv0 * exp2(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));
} }