Skip to content

Commit 75f5b51

Browse files
committed
Chapter 6 done (PC)
1 parent a4c10bd commit 75f5b51

12 files changed

Lines changed: 146 additions & 47 deletions

File tree

Chapter06/Actor.cpp

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
Actor::Actor(Game* game)
1515
:mState(EActive)
1616
,mPosition(Vector3::Zero)
17-
, mRotation(Quaternion::Identity)
17+
,mRotation(Quaternion::Identity)
1818
,mScale(1.0f)
1919
,mGame(game)
20+
,mRecomputeWorldTransform(true)
2021
{
2122
mGame->AddActor(this);
2223
}
@@ -36,8 +37,12 @@ void Actor::Update(float deltaTime)
3637
{
3738
if (mState == EActive)
3839
{
40+
ComputeWorldTransform();
41+
3942
UpdateComponents(deltaTime);
4043
UpdateActor(deltaTime);
44+
45+
ComputeWorldTransform();
4146
}
4247
}
4348

@@ -53,20 +58,60 @@ void Actor::UpdateActor(float deltaTime)
5358
{
5459
}
5560

61+
void Actor::ProcessInput(const uint8_t* keyState)
62+
{
63+
if (mState == EActive)
64+
{
65+
// First process input for components
66+
for (auto comp : mComponents)
67+
{
68+
comp->ProcessInput(keyState);
69+
}
70+
71+
ActorInput(keyState);
72+
}
73+
}
74+
75+
void Actor::ActorInput(const uint8_t* keyState)
76+
{
77+
}
78+
5679
void Actor::ComputeWorldTransform()
5780
{
58-
// Scale, then rotate, then translate
59-
mWorldTransform = Matrix4::CreateScale(mScale);
60-
mWorldTransform *= Matrix4::CreateFromQuaternion(mRotation);
61-
mWorldTransform *= Matrix4::CreateTranslation(mPosition);
81+
if (mRecomputeWorldTransform)
82+
{
83+
mRecomputeWorldTransform = false;
84+
// Scale, then rotate, then translate
85+
mWorldTransform = Matrix4::CreateScale(mScale);
86+
mWorldTransform *= Matrix4::CreateFromQuaternion(mRotation);
87+
mWorldTransform *= Matrix4::CreateTranslation(mPosition);
88+
89+
// Inform components world transform updated
90+
for (auto comp : mComponents)
91+
{
92+
comp->OnUpdateWorldTransform();
93+
}
94+
}
6295
}
6396

6497
void Actor::AddComponent(Component* component)
6598
{
66-
mComponents.emplace_back(component);
67-
std::sort(mComponents.begin(), mComponents.end(), [](Component* a, Component* b) {
68-
return a->GetUpdateOrder() < b->GetUpdateOrder();
69-
});
99+
// Find the insertion point in the sorted vector
100+
// (The first element with a order higher than me)
101+
int myOrder = component->GetUpdateOrder();
102+
auto iter = mComponents.begin();
103+
for (;
104+
iter != mComponents.end();
105+
++iter)
106+
{
107+
if (myOrder < (*iter)->GetUpdateOrder())
108+
{
109+
break;
110+
}
111+
}
112+
113+
// Inserts element before position of iterator
114+
mComponents.insert(iter, component);
70115
}
71116

72117
void Actor::RemoveComponent(Component* component)

Chapter06/Actor.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#pragma once
1010
#include <vector>
1111
#include "Math.h"
12+
#include <cstdint>
13+
1214
class Actor
1315
{
1416
public:
@@ -28,16 +30,19 @@ class Actor
2830
void UpdateComponents(float deltaTime);
2931
// Any actor-specific update code (overridable)
3032
virtual void UpdateActor(float deltaTime);
33+
34+
// ProcessInput function called from Game (not overridable)
35+
void ProcessInput(const uint8_t* keyState);
3136
// Any actor-specific input code (overridable)
32-
virtual void ProcessInput(const uint8_t* keys) { }
37+
virtual void ActorInput(const uint8_t* keyState);
3338

3439
// Getters/setters
3540
const Vector3& GetPosition() const { return mPosition; }
36-
void SetPosition(const Vector3& pos) { mPosition = pos; ComputeWorldTransform(); }
41+
void SetPosition(const Vector3& pos) { mPosition = pos; mRecomputeWorldTransform = true; }
3742
float GetScale() const { return mScale; }
38-
void SetScale(float scale) { mScale = scale; ComputeWorldTransform(); }
43+
void SetScale(float scale) { mScale = scale; mRecomputeWorldTransform = true; }
3944
const Quaternion& GetRotation() const { return mRotation; }
40-
void SetRotation(const Quaternion& rotation) { mRotation = rotation; ComputeWorldTransform(); }
45+
void SetRotation(const Quaternion& rotation) { mRotation = rotation; mRecomputeWorldTransform = true; }
4146

4247
void ComputeWorldTransform();
4348
const Matrix4& GetWorldTransform() const { return mWorldTransform; }
@@ -62,6 +67,7 @@ class Actor
6267
Vector3 mPosition;
6368
Quaternion mRotation;
6469
float mScale;
70+
bool mRecomputeWorldTransform;
6571

6672
std::vector<class Component*> mComponents;
6773
class Game* mGame;

Chapter06/CameraActor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void CameraActor::UpdateActor(float deltaTime)
3131
GetGame()->GetRenderer()->SetViewMatrix(view);
3232
}
3333

34-
void CameraActor::ProcessInput(const uint8_t* keys)
34+
void CameraActor::ActorInput(const uint8_t* keys)
3535
{
3636
float forwardSpeed = 0.0f;
3737
float angularSpeed = 0.0f;

Chapter06/CameraActor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class CameraActor : public Actor
1515
CameraActor(class Game* game);
1616

1717
void UpdateActor(float deltaTime) override;
18-
void ProcessInput(const uint8_t* keys) override;
18+
void ActorInput(const uint8_t* keys) override;
1919
private:
2020
class MoveComponent* mMoveComp;
21-
};
21+
};

Chapter06/Component.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
// ----------------------------------------------------------------
88

99
#pragma once
10+
#include <cstdint>
11+
1012
class Component
1113
{
1214
public:
@@ -17,6 +19,10 @@ class Component
1719
virtual ~Component();
1820
// Update this component by delta time
1921
virtual void Update(float deltaTime);
22+
// Process input for this component
23+
virtual void ProcessInput(const uint8_t* keyState) {}
24+
// Called when world transform changes
25+
virtual void OnUpdateWorldTransform() { }
2026

2127
int GetUpdateOrder() const { return mUpdateOrder; }
2228
protected:

Chapter06/Game.cpp

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
Game::Game()
1919
:mRenderer(nullptr)
2020
,mIsRunning(true)
21+
,mUpdatingActors(false)
2122
{
2223

2324
}
@@ -96,15 +97,21 @@ void Game::UpdateGame()
9697
}
9798
mTicksCount = SDL_GetTicks();
9899

99-
// Make copy of actor vector
100-
// (iterate over this in case new actors are created)
101-
std::vector<Actor*> copy = mActors;
102-
103100
// Update all actors
104-
for (auto actor : copy)
101+
mUpdatingActors = true;
102+
for (auto actor : mActors)
105103
{
106104
actor->Update(deltaTime);
107105
}
106+
mUpdatingActors = false;
107+
108+
// Move any pending actors to mActors
109+
for (auto pending : mPendingActors)
110+
{
111+
pending->ComputeWorldTransform();
112+
mActors.emplace_back(pending);
113+
}
114+
mPendingActors.clear();
108115

109116
// Add any dead actors to a temp vector
110117
std::vector<Actor*> deadActors;
@@ -116,8 +123,7 @@ void Game::UpdateGame()
116123
}
117124
}
118125

119-
// Delete any of the dead actors (which will
120-
// remove them from mActors)
126+
// Delete dead actors (which removes them from mActors)
121127
for (auto actor : deadActors)
122128
{
123129
delete actor;
@@ -235,12 +241,30 @@ void Game::Shutdown()
235241

236242
void Game::AddActor(Actor* actor)
237243
{
238-
mActors.emplace_back(actor);
244+
// If we're updating actors, need to add to pending
245+
if (mUpdatingActors)
246+
{
247+
mPendingActors.emplace_back(actor);
248+
}
249+
else
250+
{
251+
mActors.emplace_back(actor);
252+
}
239253
}
240254

241255
void Game::RemoveActor(Actor* actor)
242256
{
243-
auto iter = std::find(mActors.begin(), mActors.end(), actor);
257+
// Is it in pending actors?
258+
auto iter = std::find(mPendingActors.begin(), mPendingActors.end(), actor);
259+
if (iter != mPendingActors.end())
260+
{
261+
// Swap to end of vector and pop off (avoid erase copies)
262+
std::iter_swap(iter, mPendingActors.end() - 1);
263+
mPendingActors.pop_back();
264+
}
265+
266+
// Is it in actors?
267+
iter = std::find(mActors.begin(), mActors.end(), actor);
244268
if (iter != mActors.end())
245269
{
246270
// Swap to end of vector and pop off (avoid erase copies)

Chapter06/Game.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,15 @@ class Game
3434

3535
// All the actors in the game
3636
std::vector<class Actor*> mActors;
37+
// Any pending actors
38+
std::vector<class Actor*> mPendingActors;
3739

3840
class Renderer* mRenderer;
3941

4042
Uint32 mTicksCount;
4143
bool mIsRunning;
44+
// Track if we're updating actors right now
45+
bool mUpdatingActors;
4246

4347
// Game-specific code
4448
class CameraActor* mCameraActor;

Chapter06/Renderer.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,22 @@ void Renderer::Draw()
159159

160160
void Renderer::AddSprite(SpriteComponent* sprite)
161161
{
162-
mSprites.emplace_back(sprite);
163-
// Resort sprites by draw order
164-
std::sort(mSprites.begin(), mSprites.end(), [](SpriteComponent* a, SpriteComponent* b) {
165-
return a->GetDrawOrder() < b->GetDrawOrder();
166-
});
162+
// Find the insertion point in the sorted vector
163+
// (The first element with a higher draw order than me)
164+
int myDrawOrder = sprite->GetDrawOrder();
165+
auto iter = mSprites.begin();
166+
for (;
167+
iter != mSprites.end();
168+
++iter)
169+
{
170+
if (myDrawOrder < (*iter)->GetDrawOrder())
171+
{
172+
break;
173+
}
174+
}
175+
176+
// Inserts element before position of iterator
177+
mSprites.insert(iter, sprite);
167178
}
168179

169180
void Renderer::RemoveSprite(SpriteComponent* sprite)
@@ -235,7 +246,7 @@ bool Renderer::LoadShaders()
235246
{
236247
// Create sprite shader
237248
mSpriteShader = new Shader();
238-
if (!mSpriteShader->Load("Shaders/Sprite"))
249+
if (!mSpriteShader->Load("Shaders/Sprite.vert", "Shaders/Sprite.frag"))
239250
{
240251
return false;
241252
}
@@ -247,7 +258,7 @@ bool Renderer::LoadShaders()
247258

248259
// Create basic mesh shader
249260
mMeshShader = new Shader();
250-
if (!mMeshShader->Load("Shaders/Phong"))
261+
if (!mMeshShader->Load("Shaders/Phong.vert", "Shaders/Phong.frag"))
251262
{
252263
return false;
253264
}

Chapter06/Shader.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ Shader::~Shader()
2525

2626
}
2727

28-
bool Shader::Load(const std::string& name)
28+
bool Shader::Load(const std::string& vertName, const std::string& fragName)
2929
{
3030
// Compile vertex and pixel shaders
31-
if (!CompileShader(name + ".vert",
32-
GL_VERTEX_SHADER,
33-
mVertexShader) ||
34-
!CompileShader(name + ".frag",
35-
GL_FRAGMENT_SHADER,
36-
mFragShader))
31+
if (!CompileShader(vertName,
32+
GL_VERTEX_SHADER,
33+
mVertexShader) ||
34+
!CompileShader(fragName,
35+
GL_FRAGMENT_SHADER,
36+
mFragShader))
3737
{
3838
return false;
3939
}
@@ -91,14 +91,14 @@ void Shader::SetFloatUniform(const char* name, float value)
9191
}
9292

9393
bool Shader::CompileShader(const std::string& fileName,
94-
GLenum shaderType,
95-
GLuint& outShader)
94+
GLenum shaderType,
95+
GLuint& outShader)
9696
{
9797
// Open file
9898
std::ifstream shaderFile(fileName);
9999
if (shaderFile.is_open())
100100
{
101-
// Read all of the text into a string
101+
// Read all the text into a string
102102
std::stringstream sstream;
103103
sstream << shaderFile.rdbuf();
104104
std::string contents = sstream.str();

Chapter06/Shader.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ class Shader
1616
public:
1717
Shader();
1818
~Shader();
19-
// Load shader of the specified name, excluding
20-
// the .frag/.vert extension
21-
bool Load(const std::string& name);
19+
// Load the vertex/fragment shaders with the given names
20+
bool Load(const std::string& vertName, const std::string& fragName);
2221
void Unload();
2322
// Set this as the active shader program
2423
void SetActive();

0 commit comments

Comments
 (0)