diff --git a/Chapter01/Game.vcxproj b/Chapter01/Game.vcxproj
index e16204f8..2e8700f9 100644
--- a/Chapter01/Game.vcxproj
+++ b/Chapter01/Game.vcxproj
@@ -21,19 +21,19 @@
{BC508D87-495F-4554-932D-DD68388B63CC}
Win32Proj
Game
- 10.0.16299.0
+ 10.0
Application
true
- v141
+ v143
Unicode
Application
false
- v141
+ v143
true
Unicode
diff --git a/Chapter02/Game.vcxproj b/Chapter02/Game.vcxproj
index 35c39009..6f1935a5 100644
--- a/Chapter02/Game.vcxproj
+++ b/Chapter02/Game.vcxproj
@@ -35,19 +35,19 @@
{BC508D87-495F-4554-932D-DD68388B63CC}
Win32Proj
Game
- 10.0.16299.0
+ 10.0
Application
true
- v141
+ v143
Unicode
Application
false
- v141
+ v143
true
Unicode
diff --git a/Chapter03/Game.vcxproj b/Chapter03/Game.vcxproj
index fd6197c8..d3e4460d 100644
--- a/Chapter03/Game.vcxproj
+++ b/Chapter03/Game.vcxproj
@@ -43,19 +43,19 @@
{BC508D87-495F-4554-932D-DD68388B63CC}
Win32Proj
Game
- 10.0.16299.0
+ 10.0
Application
true
- v141
+ v143
Unicode
Application
false
- v141
+ v143
true
Unicode
diff --git a/Chapter04/AIComponent.cpp b/Chapter04/AIComponent.cpp
index e88ac6ab..d3c8e38e 100644
--- a/Chapter04/AIComponent.cpp
+++ b/Chapter04/AIComponent.cpp
@@ -11,44 +11,46 @@
#include "AIState.h"
#include
-AIComponent::AIComponent(class Actor* owner)
-:Component(owner)
-,mCurrentState(nullptr)
+AIComponent::AIComponent(class Actor* owner): Component(owner), pCurrentState(nullptr)
{
}
void AIComponent::Update(float deltaTime)
{
- if (mCurrentState)
+ if (pCurrentState)
{
- mCurrentState->Update(deltaTime);
+ pCurrentState->Update(deltaTime);
}
}
void AIComponent::ChangeState(const std::string& name)
{
- // First exit the current state
- if (mCurrentState)
+ if (pCurrentState)
{
- mCurrentState->OnExit();
+ // Check if we even need to change states
+ if (pCurrentState->GetName() == name)
+ {
+ return;
+ }
+ // First exit the current state
+ pCurrentState->OnExit();
}
-
// Try to find the new state from the map
auto iter = mStateMap.find(name);
if (iter != mStateMap.end())
{
- mCurrentState = iter->second;
+ pCurrentState = iter->second;
// We're entering the new state
- mCurrentState->OnEnter();
+ pCurrentState->OnEnter();
}
else
{
SDL_Log("Could not find AIState %s in state map", name.c_str());
- mCurrentState = nullptr;
+ pCurrentState = nullptr;
}
}
void AIComponent::RegisterState(AIState* state)
{
mStateMap.emplace(state->GetName(), state);
-}
+}
\ No newline at end of file
diff --git a/Chapter04/AIComponent.h b/Chapter04/AIComponent.h
index 932de9a1..ffa99960 100644
--- a/Chapter04/AIComponent.h
+++ b/Chapter04/AIComponent.h
@@ -11,19 +11,18 @@
#include
#include
-class AIComponent : public Component
+class AIComponent: public Component
{
public:
AIComponent(class Actor* owner);
-
void Update(float deltaTime) override;
void ChangeState(const std::string& name);
-
// Add a new state to the map
void RegisterState(class AIState* state);
+ class AIState* GetState() { return pCurrentState; }
private:
// Maps name of state to AIState instance
std::unordered_map mStateMap;
// Current state we're in
- class AIState* mCurrentState;
-};
+ class AIState* pCurrentState;
+};
\ No newline at end of file
diff --git a/Chapter04/AIState.cpp b/Chapter04/AIState.cpp
index 673e9b42..4ba03e95 100644
--- a/Chapter04/AIState.cpp
+++ b/Chapter04/AIState.cpp
@@ -13,11 +13,6 @@
void AIPatrol::Update(float deltaTime)
{
SDL_Log("Updating %s state", GetName());
- bool dead = true;
- if (dead)
- {
- mOwner->ChangeState("Death");
- }
}
void AIPatrol::OnEnter()
@@ -58,4 +53,4 @@ void AIAttack::OnEnter()
void AIAttack::OnExit()
{
SDL_Log("Exiting %s state", GetName());
-}
+}
\ No newline at end of file
diff --git a/Chapter04/AIState.h b/Chapter04/AIState.h
index 67ef2fd1..1fa31000 100644
--- a/Chapter04/AIState.h
+++ b/Chapter04/AIState.h
@@ -11,9 +11,8 @@
class AIState
{
public:
- AIState(class AIComponent* owner)
- :mOwner(owner)
- { }
+ AIState(class AIComponent* owner): pOwner(owner)
+ {}
// State-specific behavior
virtual void Update(float deltaTime) = 0;
virtual void OnEnter() = 0;
@@ -21,51 +20,42 @@ class AIState
// Getter for string name of state
virtual const char* GetName() const = 0;
protected:
- class AIComponent* mOwner;
+ class AIComponent* pOwner;
};
-class AIPatrol : public AIState
+class AIPatrol: public AIState
{
public:
- AIPatrol(class AIComponent* owner)
- :AIState(owner)
- { }
-
+ AIPatrol(class AIComponent* owner): AIState(owner)
+ {}
// Override with behaviors for this state
void Update(float deltaTime) override;
void OnEnter() override;
void OnExit() override;
-
const char* GetName() const override
{ return "Patrol"; }
};
-class AIDeath : public AIState
+class AIDeath: public AIState
{
public:
- AIDeath(class AIComponent* owner)
- :AIState(owner)
- { }
-
+ AIDeath(class AIComponent* owner): AIState(owner)
+ {}
void Update(float deltaTime) override;
void OnEnter() override;
void OnExit() override;
-
const char* GetName() const override
{ return "Death"; }
};
-class AIAttack : public AIState
+class AIAttack: public AIState
{
public:
- AIAttack(class AIComponent* owner)
- :AIState(owner)
- { }
-
+ AIAttack(class AIComponent* owner): AIState(owner)
+ {}
void Update(float deltaTime) override;
void OnEnter() override;
void OnExit() override;
-
const char* GetName() const override
{ return "Attack"; }
-};
+};
\ No newline at end of file
diff --git a/Chapter04/Actor.cpp b/Chapter04/Actor.cpp
index 4b8eea91..5c2fb345 100644
--- a/Chapter04/Actor.cpp
+++ b/Chapter04/Actor.cpp
@@ -11,19 +11,14 @@
#include "Component.h"
#include
-Actor::Actor(Game* game)
- :mState(EActive)
- , mPosition(Vector2::Zero)
- , mScale(1.0f)
- , mRotation(0.0f)
- , mGame(game)
+Actor::Actor(Game* game): mState(EActive), mPosition(Vector2::Zero), mScale(1.0f), mRotation(0.0f), pGame(game)
{
- mGame->AddActor(this);
+ pGame->AddActor(this);
}
Actor::~Actor()
{
- mGame->RemoveActor(this);
+ pGame->RemoveActor(this);
// Need to delete components
// Because ~Component calls RemoveComponent, need a different style loop
while (!mComponents.empty())
@@ -43,7 +38,7 @@ void Actor::Update(float deltaTime)
void Actor::UpdateComponents(float deltaTime)
{
- for (auto comp : mComponents)
+ for (auto comp: mComponents)
{
comp->Update(deltaTime);
}
@@ -58,11 +53,10 @@ void Actor::ProcessInput(const uint8_t* keyState)
if (mState == EActive)
{
// First process input for components
- for (auto comp : mComponents)
+ for (auto comp: mComponents)
{
comp->ProcessInput(keyState);
}
-
ActorInput(keyState);
}
}
@@ -77,16 +71,13 @@ void Actor::AddComponent(Component* component)
// (The first element with a order higher than me)
int myOrder = component->GetUpdateOrder();
auto iter = mComponents.begin();
- for (;
- iter != mComponents.end();
- ++iter)
+ for (; iter != mComponents.end(); ++iter)
{
if (myOrder < (*iter)->GetUpdateOrder())
{
break;
}
}
-
// Inserts element before position of iterator
mComponents.insert(iter, component);
}
@@ -98,4 +89,4 @@ void Actor::RemoveComponent(Component* component)
{
mComponents.erase(iter);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter04/Actor.h b/Chapter04/Actor.h
index 767d3c1a..c5902ec3 100644
--- a/Chapter04/Actor.h
+++ b/Chapter04/Actor.h
@@ -23,19 +23,16 @@ class Actor
Actor(class Game* game);
virtual ~Actor();
-
// Update function called from Game (not overridable)
void Update(float deltaTime);
// Updates all the components attached to the actor (not overridable)
void UpdateComponents(float deltaTime);
// Any actor-specific update code (overridable)
virtual void UpdateActor(float deltaTime);
-
// ProcessInput function called from Game (not overridable)
void ProcessInput(const uint8_t* keyState);
// Any actor-specific input code (overridable)
virtual void ActorInput(const uint8_t* keyState);
-
// Getters/setters
const Vector2& GetPosition() const { return mPosition; }
void SetPosition(const Vector2& pos) { mPosition = pos; }
@@ -43,27 +40,20 @@ class Actor
void SetScale(float scale) { mScale = scale; }
float GetRotation() const { return mRotation; }
void SetRotation(float rotation) { mRotation = rotation; }
-
Vector2 GetForward() const { return Vector2(Math::Cos(mRotation), -Math::Sin(mRotation)); }
-
State GetState() const { return mState; }
void SetState(State state) { mState = state; }
-
- class Game* GetGame() { return mGame; }
-
-
+ class Game* GetGame() { return pGame; }
// Add/remove components
void AddComponent(class Component* component);
void RemoveComponent(class Component* component);
private:
// Actor's state
State mState;
-
// Transform
Vector2 mPosition;
float mScale;
float mRotation;
-
std::vector mComponents;
- class Game* mGame;
-};
+ class Game* pGame;
+};
\ No newline at end of file
diff --git a/Chapter04/Bullet.cpp b/Chapter04/Bullet.cpp
index fddb6949..2b976b2b 100644
--- a/Chapter04/Bullet.cpp
+++ b/Chapter04/Bullet.cpp
@@ -13,29 +13,24 @@
#include "Game.h"
#include "Enemy.h"
-Bullet::Bullet(class Game* game)
-:Actor(game)
+Bullet::Bullet(class Game* game): Actor(game)
{
SpriteComponent* sc = new SpriteComponent(this);
sc->SetTexture(game->GetTexture("Assets/Projectile.png"));
-
MoveComponent* mc = new MoveComponent(this);
mc->SetForwardSpeed(400.0f);
-
- mCircle = new CircleComponent(this);
- mCircle->SetRadius(5.0f);
-
+ pCircle = new CircleComponent(this);
+ pCircle->SetRadius(5.0f);
mLiveTime = 1.0f;
}
void Bullet::UpdateActor(float deltaTime)
{
Actor::UpdateActor(deltaTime);
-
// Check for collision vs enemies
- for (Enemy* e : GetGame()->GetEnemies())
+ for (Enemy* e: GetGame()->GetEnemies())
{
- if (Intersect(*mCircle, *(e->GetCircle())))
+ if (Intersect(*pCircle, *(e->GetCircle())))
{
// We both die on collision
e->SetState(EDead);
@@ -43,11 +38,10 @@ void Bullet::UpdateActor(float deltaTime)
break;
}
}
-
mLiveTime -= deltaTime;
if (mLiveTime <= 0.0f)
{
// Time limit hit, die
SetState(EDead);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter04/Bullet.h b/Chapter04/Bullet.h
index 2c1690c4..8d033a88 100644
--- a/Chapter04/Bullet.h
+++ b/Chapter04/Bullet.h
@@ -9,12 +9,12 @@
#pragma once
#include "Actor.h"
-class Bullet : public Actor
+class Bullet: public Actor
{
public:
Bullet(class Game* game);
void UpdateActor(float deltaTime) override;
private:
- class CircleComponent* mCircle;
+ class CircleComponent* pCircle;
float mLiveTime;
-};
+};
\ No newline at end of file
diff --git a/Chapter04/CircleComponent.cpp b/Chapter04/CircleComponent.cpp
index d41aab2c..e0e31b71 100644
--- a/Chapter04/CircleComponent.cpp
+++ b/Chapter04/CircleComponent.cpp
@@ -9,21 +9,18 @@
#include "CircleComponent.h"
#include "Actor.h"
-CircleComponent::CircleComponent(class Actor* owner)
-:Component(owner)
-,mRadius(0.0f)
+CircleComponent::CircleComponent(class Actor* owner): Component(owner), mRadius(0.0f)
{
-
}
const Vector2& CircleComponent::GetCenter() const
{
- return mOwner->GetPosition();
+ return pOwner->GetPosition();
}
float CircleComponent::GetRadius() const
{
- return mOwner->GetScale() * mRadius;
+ return pOwner->GetScale() * mRadius;
}
bool Intersect(const CircleComponent& a, const CircleComponent& b)
@@ -31,10 +28,8 @@ bool Intersect(const CircleComponent& a, const CircleComponent& b)
// Calculate distance squared
Vector2 diff = a.GetCenter() - b.GetCenter();
float distSq = diff.LengthSq();
-
// Calculate sum of radii squared
float radiiSq = a.GetRadius() + b.GetRadius();
radiiSq *= radiiSq;
-
return distSq <= radiiSq;
-}
+}
\ No newline at end of file
diff --git a/Chapter04/CircleComponent.h b/Chapter04/CircleComponent.h
index 4eecb2a4..d9ef1864 100644
--- a/Chapter04/CircleComponent.h
+++ b/Chapter04/CircleComponent.h
@@ -14,13 +14,11 @@ class CircleComponent : public Component
{
public:
CircleComponent(class Actor* owner);
-
void SetRadius(float radius) { mRadius = radius; }
float GetRadius() const;
-
const Vector2& GetCenter() const;
private:
float mRadius;
};
-bool Intersect(const CircleComponent& a, const CircleComponent& b);
+bool Intersect(const CircleComponent& a, const CircleComponent& b);
\ No newline at end of file
diff --git a/Chapter04/Component.cpp b/Chapter04/Component.cpp
index c4ed432d..5446d684 100644
--- a/Chapter04/Component.cpp
+++ b/Chapter04/Component.cpp
@@ -9,19 +9,17 @@
#include "Component.h"
#include "Actor.h"
-Component::Component(Actor* owner, int updateOrder)
- :mOwner(owner)
- ,mUpdateOrder(updateOrder)
+Component::Component(Actor* owner, int updateOrder): pOwner(owner), mUpdateOrder(updateOrder)
{
// Add to actor's vector of components
- mOwner->AddComponent(this);
+ pOwner->AddComponent(this);
}
Component::~Component()
{
- mOwner->RemoveComponent(this);
+ pOwner->RemoveComponent(this);
}
void Component::Update(float deltaTime)
{
-}
+}
\ No newline at end of file
diff --git a/Chapter04/Component.h b/Chapter04/Component.h
index fb41dd75..870d895e 100644
--- a/Chapter04/Component.h
+++ b/Chapter04/Component.h
@@ -21,11 +21,10 @@ class Component
virtual void Update(float deltaTime);
// Process input for this component
virtual void ProcessInput(const uint8_t* keyState) {}
-
int GetUpdateOrder() const { return mUpdateOrder; }
protected:
// Owning actor
- class Actor* mOwner;
+ class Actor* pOwner;
// Update order of component
int mUpdateOrder;
-};
+};
\ No newline at end of file
diff --git a/Chapter04/Enemy.cpp b/Chapter04/Enemy.cpp
index ce3d5951..d1fe3dae 100644
--- a/Chapter04/Enemy.cpp
+++ b/Chapter04/Enemy.cpp
@@ -14,13 +14,12 @@
#include "Tile.h"
#include "CircleComponent.h"
#include
+#include "AIState.h"
-Enemy::Enemy(class Game* game)
-:Actor(game)
+Enemy::Enemy(class Game* game): Actor(game)
{
// Add to enemy vector
game->GetEnemies().emplace_back(this);
-
SpriteComponent* sc = new SpriteComponent(this);
sc->SetTexture(game->GetTexture("Assets/Airplane.png"));
// Set position at start tile
@@ -30,27 +29,30 @@ Enemy::Enemy(class Game* game)
nc->SetForwardSpeed(150.0f);
nc->StartPath(GetGame()->GetGrid()->GetStartTile());
// Setup a circle for collision
- mCircle = new CircleComponent(this);
- mCircle->SetRadius(25.0f);
+ pCircle = new CircleComponent(this);
+ pCircle->SetRadius(25.0f);
+ pAI = new AIComponent(this);
+ pAI->RegisterState(new AIPatrol(pAI));
+ pAI->RegisterState(new AIDeath(pAI));
+ pAI->ChangeState("Patrol");
}
Enemy::~Enemy()
{
+ pAI->ChangeState("Death");
// Remove from enemy vector
- auto iter = std::find(GetGame()->GetEnemies().begin(),
- GetGame()->GetEnemies().end(),
- this);
+ auto iter = std::find(GetGame()->GetEnemies().begin(), GetGame()->GetEnemies().end(), this);
GetGame()->GetEnemies().erase(iter);
}
void Enemy::UpdateActor(float deltaTime)
{
Actor::UpdateActor(deltaTime);
-
// Am I near the end tile?
Vector2 diff = GetPosition() - GetGame()->GetGrid()->GetEndTile()->GetPosition();
if (Math::NearZero(diff.Length(), 10.0f))
{
+ pAI->ChangeState("Death");
SetState(EDead);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter04/Enemy.h b/Chapter04/Enemy.h
index 72e33f08..0d3a00ff 100644
--- a/Chapter04/Enemy.h
+++ b/Chapter04/Enemy.h
@@ -8,14 +8,16 @@
#pragma once
#include "Actor.h"
+#include "AIComponent.h"
-class Enemy : public Actor
+class Enemy: public Actor
{
public:
Enemy(class Game* game);
~Enemy();
void UpdateActor(float deltaTime) override;
- class CircleComponent* GetCircle() { return mCircle; }
+ class CircleComponent* GetCircle() { return pCircle; }
private:
- class CircleComponent* mCircle;
-};
+ class CircleComponent* pCircle;
+ class AIComponent* pAI;
+};
\ No newline at end of file
diff --git a/Chapter04/Game.cpp b/Chapter04/Game.cpp
index c044257c..87ac6802 100644
--- a/Chapter04/Game.cpp
+++ b/Chapter04/Game.cpp
@@ -16,13 +16,8 @@
#include "AIComponent.h"
#include "AIState.h"
-Game::Game()
-:mWindow(nullptr)
-,mRenderer(nullptr)
-,mIsRunning(true)
-,mUpdatingActors(false)
+Game::Game(): pWindow(nullptr), pRenderer(nullptr), mIsRunning(true), mUpdatingActors(false)
{
-
}
bool Game::Initialize()
@@ -32,16 +27,14 @@ bool Game::Initialize()
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
return false;
}
-
- mWindow = SDL_CreateWindow("Game Programming in C++ (Chapter 4)", 100, 100, 1024, 768, 0);
- if (!mWindow)
+ pWindow = SDL_CreateWindow("Game Programming in C++ (Chapter 4)", 100, 100, 1024, 768, 0);
+ if (!pWindow)
{
SDL_Log("Failed to create window: %s", SDL_GetError());
return false;
}
-
- mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
- if (!mRenderer)
+ pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+ if (!pRenderer)
{
SDL_Log("Failed to create renderer: %s", SDL_GetError());
return false;
@@ -52,11 +45,8 @@ bool Game::Initialize()
SDL_Log("Unable to initialize SDL_image: %s", SDL_GetError());
return false;
}
-
LoadData();
-
mTicksCount = SDL_GetTicks();
-
return true;
}
@@ -82,26 +72,22 @@ void Game::ProcessInput()
break;
}
}
-
const Uint8* keyState = SDL_GetKeyboardState(NULL);
if (keyState[SDL_SCANCODE_ESCAPE])
{
mIsRunning = false;
}
-
if (keyState[SDL_SCANCODE_B])
{
- mGrid->BuildTower();
+ pGrid->BuildTower();
}
-
// Process mouse
int x, y;
Uint32 buttons = SDL_GetMouseState(&x, &y);
if (SDL_BUTTON(buttons) & SDL_BUTTON_LEFT)
{
- mGrid->ProcessClick(x, y);
+ pGrid->ProcessClick(x, y);
}
-
mUpdatingActors = true;
for (auto actor : mActors)
{
@@ -112,33 +98,28 @@ void Game::ProcessInput()
void Game::UpdateGame()
{
- // Compute delta time
+// Compute delta time:
// Wait until 16ms has elapsed since last frame
- while (!SDL_TICKS_PASSED(SDL_GetTicks(), mTicksCount + 16))
- ;
-
+ while (!SDL_TICKS_PASSED(SDL_GetTicks(), mTicksCount + 16));
float deltaTime = (SDL_GetTicks() - mTicksCount) / 1000.0f;
if (deltaTime > 0.05f)
{
deltaTime = 0.05f;
}
mTicksCount = SDL_GetTicks();
-
- // Update all actors
+// Update all actors:
mUpdatingActors = true;
for (auto actor : mActors)
{
actor->Update(deltaTime);
}
mUpdatingActors = false;
-
// Move any pending actors to mActors
for (auto pending : mPendingActors)
{
mActors.emplace_back(pending);
}
mPendingActors.clear();
-
// Add any dead actors to a temp vector
std::vector deadActors;
for (auto actor : mActors)
@@ -148,7 +129,6 @@ void Game::UpdateGame()
deadActors.emplace_back(actor);
}
}
-
// Delete dead actors (which removes them from mActors)
for (auto actor : deadActors)
{
@@ -158,21 +138,21 @@ void Game::UpdateGame()
void Game::GenerateOutput()
{
- SDL_SetRenderDrawColor(mRenderer, 34, 139, 34, 255);
- SDL_RenderClear(mRenderer);
+ SDL_SetRenderDrawColor(pRenderer, 34, 139, 34, 255);
+ SDL_RenderClear(pRenderer);
// Draw all sprite components
for (auto sprite : mSprites)
{
- sprite->Draw(mRenderer);
+ sprite->Draw(pRenderer);
}
- SDL_RenderPresent(mRenderer);
+ SDL_RenderPresent(pRenderer);
}
void Game::LoadData()
{
- mGrid = new Grid(this);
+ pGrid = new Grid(this);
// For testing AIComponent
//Actor* a = new Actor(this);
@@ -193,7 +173,6 @@ void Game::UnloadData()
{
delete mActors.back();
}
-
// Destroy textures
for (auto i : mTextures)
{
@@ -220,16 +199,14 @@ SDL_Texture* Game::GetTexture(const std::string& fileName)
SDL_Log("Failed to load texture file %s", fileName.c_str());
return nullptr;
}
-
// Create texture from surface
- tex = SDL_CreateTextureFromSurface(mRenderer, surf);
+ tex = SDL_CreateTextureFromSurface(pRenderer, surf);
SDL_FreeSurface(surf);
if (!tex)
{
SDL_Log("Failed to convert surface to texture for %s", fileName.c_str());
return nullptr;
}
-
mTextures.emplace(fileName.c_str(), tex);
}
return tex;
@@ -239,8 +216,8 @@ void Game::Shutdown()
{
UnloadData();
IMG_Quit();
- SDL_DestroyRenderer(mRenderer);
- SDL_DestroyWindow(mWindow);
+ SDL_DestroyRenderer(pRenderer);
+ SDL_DestroyWindow(pWindow);
SDL_Quit();
}
@@ -267,7 +244,6 @@ void Game::RemoveActor(Actor* actor)
std::iter_swap(iter, mPendingActors.end() - 1);
mPendingActors.pop_back();
}
-
// Is it in actors?
iter = std::find(mActors.begin(), mActors.end(), actor);
if (iter != mActors.end())
@@ -284,16 +260,13 @@ void Game::AddSprite(SpriteComponent* sprite)
// (The first element with a higher draw order than me)
int myDrawOrder = sprite->GetDrawOrder();
auto iter = mSprites.begin();
- for ( ;
- iter != mSprites.end();
- ++iter)
+ for (; iter != mSprites.end(); ++iter)
{
if (myDrawOrder < (*iter)->GetDrawOrder())
{
break;
}
}
-
// Inserts element before position of iterator
mSprites.insert(iter, sprite);
}
@@ -308,7 +281,6 @@ void Game::RemoveSprite(SpriteComponent* sprite)
Enemy* Game::GetNearestEnemy(const Vector2& pos)
{
Enemy* best = nullptr;
-
if (mEnemies.size() > 0)
{
best = mEnemies[0];
@@ -324,6 +296,5 @@ Enemy* Game::GetNearestEnemy(const Vector2& pos)
}
}
}
-
return best;
-}
+}
\ No newline at end of file
diff --git a/Chapter04/Game.h b/Chapter04/Game.h
index 56a0ecb4..577ea674 100644
--- a/Chapter04/Game.h
+++ b/Chapter04/Game.h
@@ -20,16 +20,12 @@ class Game
bool Initialize();
void RunLoop();
void Shutdown();
-
void AddActor(class Actor* actor);
void RemoveActor(class Actor* actor);
-
void AddSprite(class SpriteComponent* sprite);
void RemoveSprite(class SpriteComponent* sprite);
-
SDL_Texture* GetTexture(const std::string& fileName);
-
- class Grid* GetGrid() { return mGrid; }
+ class Grid* GetGrid() { return pGrid; }
std::vector& GetEnemies() { return mEnemies; }
class Enemy* GetNearestEnemy(const Vector2& pos);
private:
@@ -38,27 +34,22 @@ class Game
void GenerateOutput();
void LoadData();
void UnloadData();
-
// Map of textures loaded
std::unordered_map mTextures;
-
// All the actors in the game
std::vector mActors;
// Any pending actors
std::vector mPendingActors;
-
// All the sprite components drawn
std::vector mSprites;
-
- SDL_Window* mWindow;
- SDL_Renderer* mRenderer;
+ SDL_Window* pWindow;
+ SDL_Renderer* pRenderer;
Uint32 mTicksCount;
bool mIsRunning;
// Track if we're updating actors right now
bool mUpdatingActors;
-
// Game-specific
std::vector mEnemies;
- class Grid* mGrid;
+ class Grid* pGrid;
float mNextEnemy;
-};
+};
\ No newline at end of file
diff --git a/Chapter04/Game.vcxproj b/Chapter04/Game.vcxproj
index 27b091d3..ed536636 100644
--- a/Chapter04/Game.vcxproj
+++ b/Chapter04/Game.vcxproj
@@ -50,19 +50,19 @@
{BC508D87-495F-4554-932D-DD68388B63CC}
Win32Proj
Game
- 10.0.16299.0
+ 10.0
Application
true
- v141
+ v143
Unicode
Application
false
- v141
+ v143
true
Unicode
diff --git a/Chapter04/Grid.cpp b/Chapter04/Grid.cpp
index b81a7265..dd924d3f 100644
--- a/Chapter04/Grid.cpp
+++ b/Chapter04/Grid.cpp
@@ -12,9 +12,7 @@
#include "Enemy.h"
#include
-Grid::Grid(class Game* game)
-:Actor(game)
-,mSelectedTile(nullptr)
+Grid::Grid(class Game* game): Actor(game), pSelectedTile(nullptr)
{
// 7 rows, 16 columns
mTiles.resize(NumRows);
@@ -22,7 +20,6 @@ Grid::Grid(class Game* game)
{
mTiles[i].resize(NumCols);
}
-
// Create tiles
for (size_t i = 0; i < NumRows; i++)
{
@@ -32,11 +29,9 @@ Grid::Grid(class Game* game)
mTiles[i][j]->SetPosition(Vector2(TileSize/2.0f + j * TileSize, StartY + i * TileSize));
}
}
-
// Set start/end tiles
GetStartTile()->SetTileState(Tile::EStart);
GetEndTile()->SetTileState(Tile::EBase);
-
// Set up adjacency lists
for (size_t i = 0; i < NumRows; i++)
{
@@ -60,11 +55,9 @@ Grid::Grid(class Game* game)
}
}
}
-
// Find path (in reverse)
FindPath(GetEndTile(), GetStartTile());
UpdatePathTiles(GetStartTile());
-
mNextEnemy = EnemyTime;
}
@@ -75,12 +68,12 @@ void Grid::SelectTile(size_t row, size_t col)
if (tstate != Tile::EStart && tstate != Tile::EBase)
{
// Deselect previous one
- if (mSelectedTile)
+ if (pSelectedTile)
{
- mSelectedTile->ToggleSelect();
+ pSelectedTile->ToggleSelect();
}
- mSelectedTile = mTiles[row][col];
- mSelectedTile->ToggleSelect();
+ pSelectedTile = mTiles[row][col];
+ pSelectedTile->ToggleSelect();
}
}
@@ -105,28 +98,24 @@ bool Grid::FindPath(Tile* start, Tile* goal)
{
for (size_t j = 0; j < NumCols; j++)
{
- mTiles[i][j]->g = 0.0f;
+ mTiles[i][j]->mG = 0.0f;
mTiles[i][j]->mInOpenSet = false;
mTiles[i][j]->mInClosedSet = false;
}
}
-
std::vector openSet;
-
// Set current node to start, and add to closed set
Tile* current = start;
current->mInClosedSet = true;
-
do
{
// Add adjacent nodes to open set
- for (Tile* neighbor : current->mAdjacent)
+ for (Tile* neighbor: current->mAdjacent)
{
if (neighbor->mBlocked)
{
continue;
}
-
// Only check nodes that aren't in the closed set
if (!neighbor->mInClosedSet)
{
@@ -134,40 +123,37 @@ bool Grid::FindPath(Tile* start, Tile* goal)
{
// Not in the open set, so set parent
neighbor->mParent = current;
- neighbor->h = (neighbor->GetPosition() - goal->GetPosition()).Length();
+ neighbor->mH = (neighbor->GetPosition() - goal->GetPosition()).Length();
// g(x) is the parent's g plus cost of traversing edge
- neighbor->g = current->g + TileSize;
- neighbor->f = neighbor->g + neighbor->h;
+ neighbor->mG = current->mG + TileSize;
+ neighbor->mF = neighbor->mG + neighbor->mH;
openSet.emplace_back(neighbor);
neighbor->mInOpenSet = true;
}
else
{
// Compute g(x) cost if current becomes the parent
- float newG = current->g + TileSize;
- if (newG < neighbor->g)
+ float newG = current->mG + TileSize;
+ if (newG < neighbor->mG)
{
// Adopt this node
neighbor->mParent = current;
- neighbor->g = newG;
+ neighbor->mG = newG;
// f(x) changes because g(x) changes
- neighbor->f = neighbor->g + neighbor->h;
+ neighbor->mF = neighbor->mG + neighbor->mH;
}
}
}
}
-
// If open set is empty, all possible paths are exhausted
if (openSet.empty())
{
break;
}
-
// Find lowest cost node in open set
- auto iter = std::min_element(openSet.begin(), openSet.end(),
- [](Tile* a, Tile* b) {
- return a->f < b->f;
- });
+ auto iter = std::min_element(openSet.begin(), openSet.end(), [](Tile* a, Tile* b) {
+ return a->mF < b->mF;
+ });
// Set to current and move from open to closed
current = *iter;
openSet.erase(iter);
@@ -175,7 +161,6 @@ bool Grid::FindPath(Tile* start, Tile* goal)
current->mInClosedSet = true;
}
while (current != goal);
-
// Did we find a path?
return (current == goal) ? true : false;
}
@@ -193,7 +178,6 @@ void Grid::UpdatePathTiles(class Tile* start)
}
}
}
-
Tile* t = start->mParent;
while (t != GetEndTile())
{
@@ -204,18 +188,18 @@ void Grid::UpdatePathTiles(class Tile* start)
void Grid::BuildTower()
{
- if (mSelectedTile && !mSelectedTile->mBlocked)
+ if (pSelectedTile && !pSelectedTile->mBlocked)
{
- mSelectedTile->mBlocked = true;
+ pSelectedTile->mBlocked = true;
if (FindPath(GetEndTile(), GetStartTile()))
{
Tower* t = new Tower(GetGame());
- t->SetPosition(mSelectedTile->GetPosition());
+ t->SetPosition(pSelectedTile->GetPosition());
}
else
{
// This tower would block the path, so don't allow build
- mSelectedTile->mBlocked = false;
+ pSelectedTile->mBlocked = false;
FindPath(GetEndTile(), GetStartTile());
}
UpdatePathTiles(GetStartTile());
@@ -235,7 +219,6 @@ Tile* Grid::GetEndTile()
void Grid::UpdateActor(float deltaTime)
{
Actor::UpdateActor(deltaTime);
-
// Is it time to spawn a new enemy?
mNextEnemy -= deltaTime;
if (mNextEnemy <= 0.0f)
@@ -243,4 +226,4 @@ void Grid::UpdateActor(float deltaTime)
new Enemy(GetGame());
mNextEnemy += EnemyTime;
}
-}
+}
\ No newline at end of file
diff --git a/Chapter04/Grid.h b/Chapter04/Grid.h
index a69ac893..bf1f461b 100644
--- a/Chapter04/Grid.h
+++ b/Chapter04/Grid.h
@@ -10,41 +10,31 @@
#include "Actor.h"
#include
-class Grid : public Actor
+class Grid: public Actor
{
public:
Grid(class Game* game);
-
// Handle a mouse click at the x/y screen locations
void ProcessClick(int x, int y);
-
// Use A* to find a path
bool FindPath(class Tile* start, class Tile* goal);
-
// Try to build a tower
void BuildTower();
-
// Get start/end tile
class Tile* GetStartTile();
class Tile* GetEndTile();
-
void UpdateActor(float deltaTime) override;
private:
// Select a specific tile
void SelectTile(size_t row, size_t col);
-
// Update textures for tiles on path
void UpdatePathTiles(class Tile* start);
-
// Currently selected tile
- class Tile* mSelectedTile;
-
+ class Tile* pSelectedTile;
// 2D vector of tiles in grid
std::vector> mTiles;
-
// Time until next enemy
float mNextEnemy;
-
// Rows/columns in grid
const size_t NumRows = 7;
const size_t NumCols = 16;
@@ -54,4 +44,4 @@ class Grid : public Actor
const float TileSize = 64.0f;
// Time between enemies
const float EnemyTime = 1.5f;
-};
+};
\ No newline at end of file
diff --git a/Chapter04/Main.cpp b/Chapter04/Main.cpp
index 22ea0c69..625e0599 100644
--- a/Chapter04/Main.cpp
+++ b/Chapter04/Main.cpp
@@ -18,4 +18,4 @@ int main(int argc, char** argv)
}
game.Shutdown();
return 0;
-}
+}
\ No newline at end of file
diff --git a/Chapter04/Math.cpp b/Chapter04/Math.cpp
index a16e7261..c0d17507 100644
--- a/Chapter04/Math.cpp
+++ b/Chapter04/Math.cpp
@@ -39,7 +39,6 @@ static float m4Ident[4][4] =
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
};
-
const Matrix4 Matrix4::Identity(m4Ident);
const Quaternion Quaternion::Identity(0.0f, 0.0f, 0.0f, 1.0f);
@@ -56,12 +55,9 @@ Vector2 Vector2::Transform(const Vector2& vec, const Matrix3& mat, float w /*= 1
Vector3 Vector3::Transform(const Vector3& vec, const Matrix4& mat, float w /*= 1.0f*/)
{
Vector3 retVal;
- retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] +
- vec.z * mat.mat[2][0] + w * mat.mat[3][0];
- retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] +
- vec.z * mat.mat[2][1] + w * mat.mat[3][1];
- retVal.z = vec.x * mat.mat[0][2] + vec.y * mat.mat[1][2] +
- vec.z * mat.mat[2][2] + w * mat.mat[3][2];
+ retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] + vec.z * mat.mat[2][0] + w * mat.mat[3][0];
+ retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] + vec.z * mat.mat[2][1] + w * mat.mat[3][1];
+ retVal.z = vec.x * mat.mat[0][2] + vec.y * mat.mat[1][2] + vec.z * mat.mat[2][2] + w * mat.mat[3][2];
//ignore w since we aren't returning a new value for it...
return retVal;
}
@@ -70,14 +66,10 @@ Vector3 Vector3::Transform(const Vector3& vec, const Matrix4& mat, float w /*= 1
Vector3 Vector3::TransformWithPerspDiv(const Vector3& vec, const Matrix4& mat, float w /*= 1.0f*/)
{
Vector3 retVal;
- retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] +
- vec.z * mat.mat[2][0] + w * mat.mat[3][0];
- retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] +
- vec.z * mat.mat[2][1] + w * mat.mat[3][1];
- retVal.z = vec.x * mat.mat[0][2] + vec.y * mat.mat[1][2] +
- vec.z * mat.mat[2][2] + w * mat.mat[3][2];
- float transformedW = vec.x * mat.mat[0][3] + vec.y * mat.mat[1][3] +
- vec.z * mat.mat[2][3] + w * mat.mat[3][3];
+ retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] + vec.z * mat.mat[2][0] + w * mat.mat[3][0];
+ retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] + vec.z * mat.mat[2][1] + w * mat.mat[3][1];
+ retVal.z = vec.x * mat.mat[0][2] + vec.y * mat.mat[1][2] + vec.z * mat.mat[2][2] + w * mat.mat[3][2];
+ float transformedW = vec.x * mat.mat[0][3] + vec.y * mat.mat[1][3] + vec.z * mat.mat[2][3] + w * mat.mat[3][3];
if (!Math::NearZero(Math::Abs(transformedW)))
{
transformedW = 1.0f / transformedW;
@@ -104,33 +96,28 @@ void Matrix4::Invert()
float src[16];
float dst[16];
float det;
-
- // Transpose matrix
+// Transpose matrix:
// row 1 to col 1
src[0] = mat[0][0];
src[4] = mat[0][1];
src[8] = mat[0][2];
src[12] = mat[0][3];
-
// row 2 to col 2
src[1] = mat[1][0];
src[5] = mat[1][1];
src[9] = mat[1][2];
src[13] = mat[1][3];
-
// row 3 to col 3
src[2] = mat[2][0];
src[6] = mat[2][1];
src[10] = mat[2][2];
src[14] = mat[2][3];
-
// row 4 to col 4
src[3] = mat[3][0];
src[7] = mat[3][1];
src[11] = mat[3][2];
src[15] = mat[3][3];
-
- // Calculate cofactors
+// Calculate cofactors:
tmp[0] = src[10] * src[15];
tmp[1] = src[11] * src[14];
tmp[2] = src[9] * src[15];
@@ -142,8 +129,7 @@ void Matrix4::Invert()
tmp[8] = src[8] * src[14];
tmp[9] = src[10] * src[12];
tmp[10] = src[8] * src[13];
- tmp[11] = src[9] * src[12];
-
+ tmp[11] = src[9] * src[12];
dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7];
dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7];
dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7];
@@ -160,7 +146,6 @@ void Matrix4::Invert()
dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3];
dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2];
dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2];
-
tmp[0] = src[2] * src[7];
tmp[1] = src[3] * src[6];
tmp[2] = src[1] * src[7];
@@ -173,7 +158,6 @@ void Matrix4::Invert()
tmp[9] = src[2] * src[4];
tmp[10] = src[0] * src[5];
tmp[11] = src[1] * src[4];
-
dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15];
dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15];
dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15];
@@ -190,17 +174,14 @@ void Matrix4::Invert()
dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9];
dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9];
dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8];
-
// Calculate determinant
det = src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3] * dst[3];
-
// Inverse of matrix is divided by determinant
det = 1 / det;
for (int j = 0; j < 16; j++)
{
dst[j] *= det;
}
-
// Set it back
for (int i = 0; i < 4; i++)
{
@@ -214,26 +195,21 @@ void Matrix4::Invert()
Matrix4 Matrix4::CreateFromQuaternion(const class Quaternion& q)
{
float mat[4][4];
-
mat[0][0] = 1.0f - 2.0f * q.y * q.y - 2.0f * q.z * q.z;
mat[0][1] = 2.0f * q.x * q.y + 2.0f * q.w * q.z;
mat[0][2] = 2.0f * q.x * q.z - 2.0f * q.w * q.y;
mat[0][3] = 0.0f;
-
mat[1][0] = 2.0f * q.x * q.y - 2.0f * q.w * q.z;
mat[1][1] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.z * q.z;
mat[1][2] = 2.0f * q.y * q.z + 2.0f * q.w * q.x;
mat[1][3] = 0.0f;
-
mat[2][0] = 2.0f * q.x * q.z + 2.0f * q.w * q.y;
mat[2][1] = 2.0f * q.y * q.z - 2.0f * q.w * q.x;
mat[2][2] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.y * q.y;
mat[2][3] = 0.0f;
-
mat[3][0] = 0.0f;
mat[3][1] = 0.0f;
mat[3][2] = 0.0f;
mat[3][3] = 1.0f;
-
return Matrix4(mat);
-}
+}
\ No newline at end of file
diff --git a/Chapter04/Math.h b/Chapter04/Math.h
index 752963f1..a0f95813 100644
--- a/Chapter04/Math.h
+++ b/Chapter04/Math.h
@@ -24,12 +24,10 @@ namespace Math
{
return degrees * Pi / 180.0f;
}
-
inline float ToDegrees(float radians)
{
return radians * 180.0f / Pi;
}
-
inline bool NearZero(float val, float epsilon = 0.001f)
{
if (fabs(val) <= epsilon)
@@ -41,70 +39,57 @@ namespace Math
return false;
}
}
-
template
T Max(const T& a, const T& b)
{
return (a < b ? b : a);
}
-
template
T Min(const T& a, const T& b)
{
return (a < b ? a : b);
}
-
template
T Clamp(const T& value, const T& lower, const T& upper)
{
return Min(upper, Max(lower, value));
}
-
inline float Abs(float value)
{
return fabs(value);
}
-
inline float Cos(float angle)
{
return cosf(angle);
}
-
inline float Sin(float angle)
{
return sinf(angle);
}
-
inline float Tan(float angle)
{
return tanf(angle);
}
-
inline float Acos(float value)
{
return acosf(value);
}
-
inline float Atan2(float y, float x)
{
return atan2f(y, x);
}
-
inline float Cot(float angle)
{
return 1.0f / Tan(angle);
}
-
inline float Lerp(float a, float b, float f)
{
return a + f * (b - a);
}
-
inline float Sqrt(float value)
{
return sqrtf(value);
}
-
inline float Fmod(float numer, float denom)
{
return fmod(numer, denom);
@@ -118,54 +103,42 @@ class Vector2
float x;
float y;
- Vector2()
- :x(0.0f)
- ,y(0.0f)
+ Vector2(): x(0.0f), y(0.0f)
{}
-
- explicit Vector2(float inX, float inY)
- :x(inX)
- ,y(inY)
+ explicit Vector2(float inX, float inY): x(inX), y(inY)
{}
-
// Set both components in one line
void Set(float inX, float inY)
{
x = inX;
y = inY;
}
-
// Vector addition (a + b)
friend Vector2 operator+(const Vector2& a, const Vector2& b)
{
return Vector2(a.x + b.x, a.y + b.y);
}
-
// Vector subtraction (a - b)
friend Vector2 operator-(const Vector2& a, const Vector2& b)
{
return Vector2(a.x - b.x, a.y - b.y);
}
-
// Component-wise multiplication
// (a.x * b.x, ...)
friend Vector2 operator*(const Vector2& a, const Vector2& b)
{
return Vector2(a.x * b.x, a.y * b.y);
}
-
// Scalar multiplication
friend Vector2 operator*(const Vector2& vec, float scalar)
{
return Vector2(vec.x * scalar, vec.y * scalar);
}
-
// Scalar multiplication
friend Vector2 operator*(float scalar, const Vector2& vec)
{
return Vector2(vec.x * scalar, vec.y * scalar);
}
-
// Scalar *=
Vector2& operator*=(float scalar)
{
@@ -173,7 +146,6 @@ class Vector2
y *= scalar;
return *this;
}
-
// Vector +=
Vector2& operator+=(const Vector2& right)
{
@@ -181,7 +153,6 @@ class Vector2
y += right.y;
return *this;
}
-
// Vector -=
Vector2& operator-=(const Vector2& right)
{
@@ -189,19 +160,16 @@ class Vector2
y -= right.y;
return *this;
}
-
// Length squared of vector
float LengthSq() const
{
return (x*x + y*y);
}
-
// Length of vector
float Length() const
{
return (Math::Sqrt(LengthSq()));
}
-
// Normalize this vector
void Normalize()
{
@@ -209,7 +177,6 @@ class Vector2
x /= length;
y /= length;
}
-
// Normalize the provided vector
static Vector2 Normalize(const Vector2& vec)
{
@@ -217,25 +184,21 @@ class Vector2
temp.Normalize();
return temp;
}
-
// Dot product between two vectors (a dot b)
static float Dot(const Vector2& a, const Vector2& b)
{
return (a.x * b.x + a.y * b.y);
}
-
// Lerp from A to B by f
static Vector2 Lerp(const Vector2& a, const Vector2& b, float f)
{
return Vector2(a + f * (b - a));
}
-
// Reflect V about (normalized) N
static Vector2 Reflect(const Vector2& v, const Vector2& n)
{
return v - 2.0f * Vector2::Dot(v, n) * n;
}
-
// Transform vector by matrix
static Vector2 Transform(const Vector2& vec, const class Matrix3& mat, float w = 1.0f);
@@ -254,24 +217,15 @@ class Vector3
float y;
float z;
- Vector3()
- :x(0.0f)
- ,y(0.0f)
- ,z(0.0f)
+ Vector3(): x(0.0f), y(0.0f), z(0.0f)
{}
-
- explicit Vector3(float inX, float inY, float inZ)
- :x(inX)
- ,y(inY)
- ,z(inZ)
+ explicit Vector3(float inX, float inY, float inZ): x(inX), y(inY), z(inZ)
{}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&x);
}
-
// Set all three components in one line
void Set(float inX, float inY, float inZ)
{
@@ -279,37 +233,31 @@ class Vector3
y = inY;
z = inZ;
}
-
// Vector addition (a + b)
friend Vector3 operator+(const Vector3& a, const Vector3& b)
{
return Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
}
-
// Vector subtraction (a - b)
friend Vector3 operator-(const Vector3& a, const Vector3& b)
{
return Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
}
-
// Component-wise multiplication
friend Vector3 operator*(const Vector3& left, const Vector3& right)
{
return Vector3(left.x * right.x, left.y * right.y, left.z * right.z);
}
-
// Scalar multiplication
friend Vector3 operator*(const Vector3& vec, float scalar)
{
return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
}
-
// Scalar multiplication
friend Vector3 operator*(float scalar, const Vector3& vec)
{
return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
}
-
// Scalar *=
Vector3& operator*=(float scalar)
{
@@ -318,7 +266,6 @@ class Vector3
z *= scalar;
return *this;
}
-
// Vector +=
Vector3& operator+=(const Vector3& right)
{
@@ -327,7 +274,6 @@ class Vector3
z += right.z;
return *this;
}
-
// Vector -=
Vector3& operator-=(const Vector3& right)
{
@@ -336,19 +282,16 @@ class Vector3
z -= right.z;
return *this;
}
-
// Length squared of vector
float LengthSq() const
{
return (x*x + y*y + z*z);
}
-
// Length of vector
float Length() const
{
return (Math::Sqrt(LengthSq()));
}
-
// Normalize this vector
void Normalize()
{
@@ -357,7 +300,6 @@ class Vector3
y /= length;
z /= length;
}
-
// Normalize the provided vector
static Vector3 Normalize(const Vector3& vec)
{
@@ -365,13 +307,11 @@ class Vector3
temp.Normalize();
return temp;
}
-
// Dot product between two vectors (a dot b)
static float Dot(const Vector3& a, const Vector3& b)
{
return (a.x * b.x + a.y * b.y + a.z * b.z);
}
-
// Cross product between two vectors (a cross b)
static Vector3 Cross(const Vector3& a, const Vector3& b)
{
@@ -381,23 +321,19 @@ class Vector3
temp.z = a.x * b.y - a.y * b.x;
return temp;
}
-
// Lerp from A to B by f
static Vector3 Lerp(const Vector3& a, const Vector3& b, float f)
{
return Vector3(a + f * (b - a));
}
-
// Reflect V about (normalized) N
static Vector3 Reflect(const Vector3& v, const Vector3& n)
{
return v - 2.0f * Vector3::Dot(v, n) * n;
}
-
static Vector3 Transform(const Vector3& vec, const class Matrix4& mat, float w = 1.0f);
// This will transform the vector and renormalize the w component
static Vector3 TransformWithPerspDiv(const Vector3& vec, const class Matrix4& mat, float w = 1.0f);
-
// Transform a Vector3 by a quaternion
static Vector3 Transform(const Vector3& v, const class Quaternion& q);
@@ -422,18 +358,15 @@ class Matrix3
{
*this = Matrix3::Identity;
}
-
explicit Matrix3(float inMat[3][3])
{
memcpy(mat, inMat, 9 * sizeof(float));
}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&mat[0][0]);
}
-
// Matrix multiplication
friend Matrix3 operator*(const Matrix3& left, const Matrix3& right)
{
@@ -443,58 +376,47 @@ class Matrix3
left.mat[0][0] * right.mat[0][0] +
left.mat[0][1] * right.mat[1][0] +
left.mat[0][2] * right.mat[2][0];
-
retVal.mat[0][1] =
left.mat[0][0] * right.mat[0][1] +
left.mat[0][1] * right.mat[1][1] +
left.mat[0][2] * right.mat[2][1];
-
retVal.mat[0][2] =
left.mat[0][0] * right.mat[0][2] +
left.mat[0][1] * right.mat[1][2] +
left.mat[0][2] * right.mat[2][2];
-
// row 1
retVal.mat[1][0] =
left.mat[1][0] * right.mat[0][0] +
left.mat[1][1] * right.mat[1][0] +
left.mat[1][2] * right.mat[2][0];
-
retVal.mat[1][1] =
left.mat[1][0] * right.mat[0][1] +
left.mat[1][1] * right.mat[1][1] +
left.mat[1][2] * right.mat[2][1];
-
retVal.mat[1][2] =
left.mat[1][0] * right.mat[0][2] +
left.mat[1][1] * right.mat[1][2] +
left.mat[1][2] * right.mat[2][2];
-
// row 2
retVal.mat[2][0] =
left.mat[2][0] * right.mat[0][0] +
left.mat[2][1] * right.mat[1][0] +
left.mat[2][2] * right.mat[2][0];
-
retVal.mat[2][1] =
left.mat[2][0] * right.mat[0][1] +
left.mat[2][1] * right.mat[1][1] +
left.mat[2][2] * right.mat[2][1];
-
retVal.mat[2][2] =
left.mat[2][0] * right.mat[0][2] +
left.mat[2][1] * right.mat[1][2] +
left.mat[2][2] * right.mat[2][2];
-
return retVal;
}
-
Matrix3& operator*=(const Matrix3& right)
{
*this = *this * right;
return *this;
}
-
// Create a scale matrix with x and y scales
static Matrix3 CreateScale(float xScale, float yScale)
{
@@ -506,18 +428,15 @@ class Matrix3
};
return Matrix3(temp);
}
-
static Matrix3 CreateScale(const Vector2& scaleVector)
{
return CreateScale(scaleVector.x, scaleVector.y);
}
-
// Create a scale matrix with a uniform factor
static Matrix3 CreateScale(float scale)
{
return CreateScale(scale, scale);
}
-
// Create a rotation matrix about the Z axis
// theta is in radians
static Matrix3 CreateRotation(float theta)
@@ -530,7 +449,6 @@ class Matrix3
};
return Matrix3(temp);
}
-
// Create a translation matrix (on the xy-plane)
static Matrix3 CreateTranslation(const Vector2& trans)
{
@@ -542,7 +460,6 @@ class Matrix3
};
return Matrix3(temp);
}
-
static const Matrix3 Identity;
};
@@ -556,18 +473,15 @@ class Matrix4
{
*this = Matrix4::Identity;
}
-
explicit Matrix4(float inMat[4][4])
{
memcpy(mat, inMat, 16 * sizeof(float));
}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&mat[0][0]);
}
-
// Matrix multiplication (a * b)
friend Matrix4 operator*(const Matrix4& a, const Matrix4& b)
{
@@ -578,136 +492,113 @@ class Matrix4
a.mat[0][1] * b.mat[1][0] +
a.mat[0][2] * b.mat[2][0] +
a.mat[0][3] * b.mat[3][0];
-
retVal.mat[0][1] =
a.mat[0][0] * b.mat[0][1] +
a.mat[0][1] * b.mat[1][1] +
a.mat[0][2] * b.mat[2][1] +
a.mat[0][3] * b.mat[3][1];
-
retVal.mat[0][2] =
a.mat[0][0] * b.mat[0][2] +
a.mat[0][1] * b.mat[1][2] +
a.mat[0][2] * b.mat[2][2] +
a.mat[0][3] * b.mat[3][2];
-
retVal.mat[0][3] =
a.mat[0][0] * b.mat[0][3] +
a.mat[0][1] * b.mat[1][3] +
a.mat[0][2] * b.mat[2][3] +
a.mat[0][3] * b.mat[3][3];
-
// row 1
retVal.mat[1][0] =
a.mat[1][0] * b.mat[0][0] +
a.mat[1][1] * b.mat[1][0] +
a.mat[1][2] * b.mat[2][0] +
a.mat[1][3] * b.mat[3][0];
-
retVal.mat[1][1] =
a.mat[1][0] * b.mat[0][1] +
a.mat[1][1] * b.mat[1][1] +
a.mat[1][2] * b.mat[2][1] +
a.mat[1][3] * b.mat[3][1];
-
retVal.mat[1][2] =
a.mat[1][0] * b.mat[0][2] +
a.mat[1][1] * b.mat[1][2] +
a.mat[1][2] * b.mat[2][2] +
a.mat[1][3] * b.mat[3][2];
-
retVal.mat[1][3] =
a.mat[1][0] * b.mat[0][3] +
a.mat[1][1] * b.mat[1][3] +
a.mat[1][2] * b.mat[2][3] +
a.mat[1][3] * b.mat[3][3];
-
// row 2
retVal.mat[2][0] =
a.mat[2][0] * b.mat[0][0] +
a.mat[2][1] * b.mat[1][0] +
a.mat[2][2] * b.mat[2][0] +
a.mat[2][3] * b.mat[3][0];
-
retVal.mat[2][1] =
a.mat[2][0] * b.mat[0][1] +
a.mat[2][1] * b.mat[1][1] +
a.mat[2][2] * b.mat[2][1] +
a.mat[2][3] * b.mat[3][1];
-
retVal.mat[2][2] =
a.mat[2][0] * b.mat[0][2] +
a.mat[2][1] * b.mat[1][2] +
a.mat[2][2] * b.mat[2][2] +
a.mat[2][3] * b.mat[3][2];
-
retVal.mat[2][3] =
a.mat[2][0] * b.mat[0][3] +
a.mat[2][1] * b.mat[1][3] +
a.mat[2][2] * b.mat[2][3] +
a.mat[2][3] * b.mat[3][3];
-
// row 3
retVal.mat[3][0] =
a.mat[3][0] * b.mat[0][0] +
a.mat[3][1] * b.mat[1][0] +
a.mat[3][2] * b.mat[2][0] +
a.mat[3][3] * b.mat[3][0];
-
retVal.mat[3][1] =
a.mat[3][0] * b.mat[0][1] +
a.mat[3][1] * b.mat[1][1] +
a.mat[3][2] * b.mat[2][1] +
a.mat[3][3] * b.mat[3][1];
-
retVal.mat[3][2] =
a.mat[3][0] * b.mat[0][2] +
a.mat[3][1] * b.mat[1][2] +
a.mat[3][2] * b.mat[2][2] +
a.mat[3][3] * b.mat[3][2];
-
retVal.mat[3][3] =
a.mat[3][0] * b.mat[0][3] +
a.mat[3][1] * b.mat[1][3] +
a.mat[3][2] * b.mat[2][3] +
a.mat[3][3] * b.mat[3][3];
-
return retVal;
}
-
Matrix4& operator*=(const Matrix4& right)
{
*this = *this * right;
return *this;
}
-
// Invert the matrix - super slow
void Invert();
-
// Get the translation component of the matrix
Vector3 GetTranslation() const
{
return Vector3(mat[3][0], mat[3][1], mat[3][2]);
}
-
// Get the X axis of the matrix (forward)
Vector3 GetXAxis() const
{
return Vector3::Normalize(Vector3(mat[0][0], mat[0][1], mat[0][2]));
}
-
// Get the Y axis of the matrix (left)
Vector3 GetYAxis() const
{
return Vector3::Normalize(Vector3(mat[1][0], mat[1][1], mat[1][2]));
}
-
// Get the Z axis of the matrix (up)
Vector3 GetZAxis() const
{
return Vector3::Normalize(Vector3(mat[2][0], mat[2][1], mat[2][2]));
}
-
// Extract the scale component from the matrix
Vector3 GetScale() const
{
@@ -717,7 +608,6 @@ class Matrix4
retVal.z = Vector3(mat[2][0], mat[2][1], mat[2][2]).Length();
return retVal;
}
-
// Create a scale matrix with x, y, and z scales
static Matrix4 CreateScale(float xScale, float yScale, float zScale)
{
@@ -730,18 +620,15 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateScale(const Vector3& scaleVector)
{
return CreateScale(scaleVector.x, scaleVector.y, scaleVector.z);
}
-
// Create a scale matrix with a uniform factor
static Matrix4 CreateScale(float scale)
{
return CreateScale(scale, scale, scale);
}
-
// Rotation about x-axis
static Matrix4 CreateRotationX(float theta)
{
@@ -754,7 +641,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Rotation about y-axis
static Matrix4 CreateRotationY(float theta)
{
@@ -767,7 +653,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Rotation about z-axis
static Matrix4 CreateRotationZ(float theta)
{
@@ -780,10 +665,8 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Create a rotation matrix from a quaternion
static Matrix4 CreateFromQuaternion(const class Quaternion& q);
-
static Matrix4 CreateTranslation(const Vector3& trans)
{
float temp[4][4] =
@@ -795,7 +678,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
{
Vector3 zaxis = Vector3::Normalize(target - eye);
@@ -805,7 +687,6 @@ class Matrix4
trans.x = -Vector3::Dot(xaxis, eye);
trans.y = -Vector3::Dot(yaxis, eye);
trans.z = -Vector3::Dot(zaxis, eye);
-
float temp[4][4] =
{
{ xaxis.x, yaxis.x, zaxis.x, 0.0f },
@@ -815,7 +696,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateOrtho(float width, float height, float near, float far)
{
float temp[4][4] =
@@ -827,7 +707,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreatePerspectiveFOV(float fovY, float width, float height, float near, float far)
{
float yScale = Math::Cot(fovY / 2.0f);
@@ -841,7 +720,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Create "Simple" View-Projection Matrix from Chapter 6
static Matrix4 CreateSimpleViewProj(float width, float height)
{
@@ -854,7 +732,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static const Matrix4 Identity;
};
@@ -871,17 +748,13 @@ class Quaternion
{
*this = Quaternion::Identity;
}
-
- // This directly sets the quaternion components --
- // don't use for axis/angle
+ // This directly sets the quaternion components -- don't use for axis/angle
explicit Quaternion(float inX, float inY, float inZ, float inW)
{
Set(inX, inY, inZ, inW);
}
-
// Construct the quaternion from an axis and angle
- // It is assumed that axis is already normalized,
- // and the angle is in radians
+ // It is assumed that axis is already normalized, and the angle is in radians
explicit Quaternion(const Vector3& axis, float angle)
{
float scalar = Math::Sin(angle / 2.0f);
@@ -890,7 +763,6 @@ class Quaternion
z = axis.z * scalar;
w = Math::Cos(angle / 2.0f);
}
-
// Directly set the internal components
void Set(float inX, float inY, float inZ, float inW)
{
@@ -899,24 +771,20 @@ class Quaternion
z = inZ;
w = inW;
}
-
void Conjugate()
{
x *= -1.0f;
y *= -1.0f;
z *= -1.0f;
}
-
float LengthSq() const
{
return (x*x + y*y + z*z + w*w);
}
-
float Length() const
{
return Math::Sqrt(LengthSq());
}
-
void Normalize()
{
float length = Length();
@@ -925,7 +793,6 @@ class Quaternion
z /= length;
w /= length;
}
-
// Normalize the provided quaternion
static Quaternion Normalize(const Quaternion& q)
{
@@ -933,7 +800,6 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
// Linear interpolation
static Quaternion Lerp(const Quaternion& a, const Quaternion& b, float f)
{
@@ -945,25 +811,20 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
static float Dot(const Quaternion& a, const Quaternion& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}
-
// Spherical Linear Interpolation
static Quaternion Slerp(const Quaternion& a, const Quaternion& b, float f)
{
float rawCosm = Quaternion::Dot(a, b);
-
float cosom = -rawCosm;
if (rawCosm >= 0.0f)
{
cosom = rawCosm;
}
-
float scale0, scale1;
-
if (cosom < 0.9999f)
{
const float omega = Math::Acos(cosom);
@@ -973,17 +834,14 @@ class Quaternion
}
else
{
- // Use linear interpolation if the quaternions
- // are collinear
+ // Use linear interpolation if the quaternions are collinear
scale0 = 1.0f - f;
scale1 = f;
}
-
if (rawCosm < 0.0f)
{
scale1 = -scale1;
}
-
Quaternion retVal;
retVal.x = scale0 * a.x + scale1 * b.x;
retVal.y = scale0 * a.y + scale1 * b.y;
@@ -1007,11 +865,9 @@ class Quaternion
retVal.x = newVec.x;
retVal.y = newVec.y;
retVal.z = newVec.z;
-
// Scalar component is:
// ps * qs - pv . qv
retVal.w = p.w * q.w - Vector3::Dot(pv, qv);
-
return retVal;
}
@@ -1030,4 +886,4 @@ namespace Color
static const Vector3 LightBlue(0.68f, 0.85f, 0.9f);
static const Vector3 LightPink(1.0f, 0.71f, 0.76f);
static const Vector3 LightGreen(0.56f, 0.93f, 0.56f);
-}
+}
\ No newline at end of file
diff --git a/Chapter04/MoveComponent.cpp b/Chapter04/MoveComponent.cpp
index cdf1fdf9..fad01c0d 100644
--- a/Chapter04/MoveComponent.cpp
+++ b/Chapter04/MoveComponent.cpp
@@ -9,27 +9,22 @@
#include "MoveComponent.h"
#include "Actor.h"
-MoveComponent::MoveComponent(class Actor* owner, int updateOrder)
-:Component(owner, updateOrder)
-,mAngularSpeed(0.0f)
-,mForwardSpeed(0.0f)
+MoveComponent::MoveComponent(class Actor* owner, int updateOrder): Component(owner, updateOrder), mAngularSpeed(0.0f), mForwardSpeed(0.0f)
{
-
}
void MoveComponent::Update(float deltaTime)
{
if (!Math::NearZero(mAngularSpeed))
{
- float rot = mOwner->GetRotation();
+ float rot = pOwner->GetRotation();
rot += mAngularSpeed * deltaTime;
- mOwner->SetRotation(rot);
+ pOwner->SetRotation(rot);
}
-
if (!Math::NearZero(mForwardSpeed))
{
- Vector2 pos = mOwner->GetPosition();
- pos += mOwner->GetForward() * mForwardSpeed * deltaTime;
- mOwner->SetPosition(pos);
+ Vector2 pos = pOwner->GetPosition();
+ pos += pOwner->GetForward() * mForwardSpeed * deltaTime;
+ pOwner->SetPosition(pos);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter04/MoveComponent.h b/Chapter04/MoveComponent.h
index def7d389..c737e66b 100644
--- a/Chapter04/MoveComponent.h
+++ b/Chapter04/MoveComponent.h
@@ -9,13 +9,12 @@
#pragma once
#include "Component.h"
-class MoveComponent : public Component
+class MoveComponent: public Component
{
public:
// Lower update order to update first
MoveComponent(class Actor* owner, int updateOrder = 10);
void Update(float deltaTime) override;
-
float GetAngularSpeed() const { return mAngularSpeed; }
float GetForwardSpeed() const { return mForwardSpeed; }
void SetAngularSpeed(float speed) { mAngularSpeed = speed; }
@@ -23,4 +22,4 @@ class MoveComponent : public Component
private:
float mAngularSpeed;
float mForwardSpeed;
-};
+};
\ No newline at end of file
diff --git a/Chapter04/NavComponent.cpp b/Chapter04/NavComponent.cpp
index a80d38ce..ed95680e 100644
--- a/Chapter04/NavComponent.cpp
+++ b/Chapter04/NavComponent.cpp
@@ -9,41 +9,37 @@
#include "NavComponent.h"
#include "Tile.h"
-NavComponent::NavComponent(class Actor* owner, int updateOrder)
-:MoveComponent(owner, updateOrder)
-,mNextNode(nullptr)
+NavComponent::NavComponent(class Actor* owner, int updateOrder): MoveComponent(owner, updateOrder), pNextNode(nullptr)
{
-
}
void NavComponent::Update(float deltaTime)
{
- if (mNextNode)
+ if (pNextNode)
{
// If we're at the next node, advance along path
- Vector2 diff = mOwner->GetPosition() - mNextNode->GetPosition();
+ Vector2 diff = pOwner->GetPosition() - pNextNode->GetPosition();
if (Math::NearZero(diff.Length(), 2.0f))
{
- mNextNode = mNextNode->GetParent();
- TurnTo(mNextNode->GetPosition());
+ pNextNode = pNextNode->GetParent();
+ TurnTo(pNextNode->GetPosition());
}
}
-
MoveComponent::Update(deltaTime);
}
void NavComponent::StartPath(const Tile* start)
{
- mNextNode = start->GetParent();
- TurnTo(mNextNode->GetPosition());
+ pNextNode = start->GetParent();
+ TurnTo(pNextNode->GetPosition());
}
void NavComponent::TurnTo(const Vector2& pos)
{
// Vector from me to pos
- Vector2 dir = pos - mOwner->GetPosition();
+ Vector2 dir = pos - pOwner->GetPosition();
// New angle is just atan2 of this dir vector
// (Negate y because +y is down on screen)
float angle = Math::Atan2(-dir.y, dir.x);
- mOwner->SetRotation(angle);
-}
+ pOwner->SetRotation(angle);
+}
\ No newline at end of file
diff --git a/Chapter04/NavComponent.h b/Chapter04/NavComponent.h
index b79c721f..acd98437 100644
--- a/Chapter04/NavComponent.h
+++ b/Chapter04/NavComponent.h
@@ -10,7 +10,7 @@
#include "MoveComponent.h"
#include "Math.h"
-class NavComponent : public MoveComponent
+class NavComponent: public MoveComponent
{
public:
// Lower update order to update first
@@ -19,5 +19,5 @@ class NavComponent : public MoveComponent
void StartPath(const class Tile* start);
void TurnTo(const Vector2& pos);
private:
- const class Tile* mNextNode;
-};
+ const class Tile* pNextNode;
+};
\ No newline at end of file
diff --git a/Chapter04/Search.cpp b/Chapter04/Search.cpp
index ce1e6f41..b0491b1c 100644
--- a/Chapter04/Search.cpp
+++ b/Chapter04/Search.cpp
@@ -20,8 +20,8 @@ struct Graph
struct WeightedEdge
{
// Which nodes are connected by this edge?
- struct WeightedGraphNode* mFrom;
- struct WeightedGraphNode* mTo;
+ struct WeightedGraphNode* pFrom;
+ struct WeightedGraphNode* pTo;
// Weight of this edge
float mWeight;
};
@@ -38,47 +38,42 @@ struct WeightedGraph
struct GBFSScratch
{
- const WeightedEdge* mParentEdge = nullptr;
+ const WeightedEdge* pParentEdge = nullptr;
float mHeuristic = 0.0f;
bool mInOpenSet = false;
bool mInClosedSet = false;
};
-using GBFSMap =
-std::unordered_map;
+using GBFSMap = std::unordered_map;
struct AStarScratch
{
- const WeightedEdge* mParentEdge = nullptr;
+ const WeightedEdge* pParentEdge = nullptr;
float mHeuristic = 0.0f;
float mActualFromStart = 0.0f;
bool mInOpenSet = false;
bool mInClosedSet = false;
};
-using AStarMap =
-std::unordered_map;
+using AStarMap = std::unordered_map;
float ComputeHeuristic(const WeightedGraphNode* a, const WeightedGraphNode* b)
{
return 0.0f;
}
-bool AStar(const WeightedGraph& g, const WeightedGraphNode* start,
- const WeightedGraphNode* goal, AStarMap& outMap)
+bool AStar(const WeightedGraph& g, const WeightedGraphNode* start, const WeightedGraphNode* goal, AStarMap& outMap)
{
std::vector openSet;
-
// Set current node to start, and mark in closed set
const WeightedGraphNode* current = start;
outMap[current].mInClosedSet = true;
-
do
{
// Add adjacent nodes to open set
for (const WeightedEdge* edge : current->mEdges)
{
- const WeightedGraphNode* neighbor = edge->mTo;
+ const WeightedGraphNode* neighbor = edge->pTo;
// Get scratch data for this node
AStarScratch& data = outMap[neighbor];
// Only check nodes that aren't in the closed set
@@ -87,11 +82,10 @@ bool AStar(const WeightedGraph& g, const WeightedGraphNode* start,
if (!data.mInOpenSet)
{
// Not in the open set, so parent must be current
- data.mParentEdge = edge;
+ data.pParentEdge = edge;
data.mHeuristic = ComputeHeuristic(neighbor, goal);
// Actual cost is the parent's plus cost of traversing edge
- data.mActualFromStart = outMap[current].mActualFromStart +
- edge->mWeight;
+ data.mActualFromStart = outMap[current].mActualFromStart + edge->mWeight;
data.mInOpenSet = true;
openSet.emplace_back(neighbor);
}
@@ -102,22 +96,19 @@ bool AStar(const WeightedGraph& g, const WeightedGraphNode* start,
if (newG < data.mActualFromStart)
{
// Current should adopt this node
- data.mParentEdge = edge;
+ data.pParentEdge = edge;
data.mActualFromStart = newG;
}
}
}
}
-
// If open set is empty, all possible paths are exhausted
if (openSet.empty())
{
break;
}
-
// Find lowest cost node in open set
- auto iter = std::min_element(openSet.begin(), openSet.end(),
- [&outMap](const WeightedGraphNode* a, const WeightedGraphNode* b) {
+ auto iter = std::min_element(openSet.begin(), openSet.end(), [&outMap](const WeightedGraphNode* a, const WeightedGraphNode* b) {
// Calculate f(x) for nodes a/b
float fOfA = outMap[a].mHeuristic + outMap[a].mActualFromStart;
float fOfB = outMap[b].mHeuristic + outMap[b].mActualFromStart;
@@ -129,67 +120,57 @@ bool AStar(const WeightedGraph& g, const WeightedGraphNode* start,
outMap[current].mInOpenSet = true;
outMap[current].mInClosedSet = true;
} while (current != goal);
-
// Did we find a path?
return (current == goal) ? true : false;
}
-bool GBFS(const WeightedGraph& g, const WeightedGraphNode* start,
- const WeightedGraphNode* goal, GBFSMap& outMap)
+bool GBFS(const WeightedGraph& g, const WeightedGraphNode* start, const WeightedGraphNode* goal, GBFSMap& outMap)
{
std::vector openSet;
-
// Set current node to start, and mark in closed set
const WeightedGraphNode* current = start;
outMap[current].mInClosedSet = true;
-
do
{
// Add adjacent nodes to open set
for (const WeightedEdge* edge : current->mEdges)
{
// Get scratch data for this node
- GBFSScratch& data = outMap[edge->mTo];
+ GBFSScratch& data = outMap[edge->pTo];
// Add it only if it's not in the closed set
if (!data.mInClosedSet)
{
// Set the adjacent node's parent edge
- data.mParentEdge = edge;
+ data.pParentEdge = edge;
if (!data.mInOpenSet)
{
// Compute the heuristic for this node, and add to open set
- data.mHeuristic = ComputeHeuristic(edge->mTo, goal);
+ data.mHeuristic = ComputeHeuristic(edge->pTo, goal);
data.mInOpenSet = true;
- openSet.emplace_back(edge->mTo);
+ openSet.emplace_back(edge->pTo);
}
}
}
-
// If open set is empty, all possible paths are exhausted
if (openSet.empty())
{
break;
}
-
// Find lowest cost node in open set
- auto iter = std::min_element(openSet.begin(), openSet.end(),
- [&outMap](const WeightedGraphNode* a, const WeightedGraphNode* b) {
+ auto iter = std::min_element(openSet.begin(), openSet.end(), [&outMap](const WeightedGraphNode* a, const WeightedGraphNode* b) {
return outMap[a].mHeuristic < outMap[b].mHeuristic;
});
-
// Set to current and move from open to closed
current = *iter;
openSet.erase(iter);
outMap[current].mInOpenSet = false;
outMap[current].mInClosedSet = true;
} while (current != goal);
-
// Did we find a path?
return (current == goal) ? true : false;
}
-using NodeToParentMap =
-std::unordered_map;
+using NodeToParentMap = std::unordered_map;
bool BFS(const Graph& graph, const GraphNode* start, const GraphNode* goal, NodeToParentMap& outMap)
{
@@ -199,7 +180,6 @@ bool BFS(const Graph& graph, const GraphNode* start, const GraphNode* goal, Node
std::queue q;
// Enqueue the first node
q.emplace(start);
-
while (!q.empty())
{
// Dequeue a node
@@ -210,7 +190,6 @@ bool BFS(const Graph& graph, const GraphNode* start, const GraphNode* goal, Node
pathFound = true;
break;
}
-
// Enqueue adjacent nodes that aren't already in the queue
for (const GraphNode* node : current->mAdjacent)
{
@@ -225,7 +204,6 @@ bool BFS(const Graph& graph, const GraphNode* start, const GraphNode* goal, Node
}
}
}
-
return pathFound;
}
@@ -240,7 +218,6 @@ void testBFS()
g.mNodes.emplace_back(node);
}
}
-
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
@@ -264,7 +241,6 @@ void testBFS()
}
}
}
-
NodeToParentMap map;
bool found = BFS(g, g.mNodes[0], g.mNodes[9], map);
std::cout << found << '\n';
@@ -281,7 +257,6 @@ void testHeuristic(bool useAStar)
g.mNodes.emplace_back(node);
}
}
-
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
@@ -290,32 +265,32 @@ void testHeuristic(bool useAStar)
if (i > 0)
{
WeightedEdge* e = new WeightedEdge;
- e->mFrom = node;
- e->mTo = g.mNodes[(i - 1) * 5 + j];
+ e->pFrom = node;
+ e->pTo = g.mNodes[(i - 1) * 5 + j];
e->mWeight = 1.0f;
node->mEdges.emplace_back(e);
}
if (i < 4)
{
WeightedEdge* e = new WeightedEdge;
- e->mFrom = node;
- e->mTo = g.mNodes[(i + 1) * 5 + j];
+ e->pFrom = node;
+ e->pTo = g.mNodes[(i + 1) * 5 + j];
e->mWeight = 1.0f;
node->mEdges.emplace_back(e);
}
if (j > 0)
{
WeightedEdge* e = new WeightedEdge;
- e->mFrom = node;
- e->mTo = g.mNodes[i * 5 + j - 1];
+ e->pFrom = node;
+ e->pTo = g.mNodes[i * 5 + j - 1];
e->mWeight = 1.0f;
node->mEdges.emplace_back(e);
}
if (j < 4)
{
WeightedEdge* e = new WeightedEdge;
- e->mFrom = node;
- e->mTo = g.mNodes[i * 5 + j + 1];
+ e->pFrom = node;
+ e->pTo = g.mNodes[i * 5 + j + 1];
e->mWeight = 1.0f;
node->mEdges.emplace_back(e);
}
@@ -382,7 +357,6 @@ float GetScore(const GameState& state)
same = false;
}
}
-
if (same)
{
if (v == GameState::X)
@@ -395,7 +369,6 @@ float GetScore(const GameState& state)
}
}
}
-
// Are any of the columns the same?
for (int j = 0; j < 3; j++)
{
@@ -408,7 +381,6 @@ float GetScore(const GameState& state)
same = false;
}
}
-
if (same)
{
if (v == GameState::X)
@@ -421,12 +393,8 @@ float GetScore(const GameState& state)
}
}
}
-
// What about diagonals?
- if (((state.mBoard[0][0] == state.mBoard[1][1]) &&
- (state.mBoard[1][1] == state.mBoard[2][2])) ||
- ((state.mBoard[2][0] == state.mBoard[1][1]) &&
- (state.mBoard[1][1] == state.mBoard[0][2])))
+ if (((state.mBoard[0][0] == state.mBoard[1][1]) && (state.mBoard[1][1] == state.mBoard[2][2])) || ((state.mBoard[2][0] == state.mBoard[1][1]) && (state.mBoard[1][1] == state.mBoard[0][2])))
{
if (state.mBoard[1][1] == GameState::X)
{
@@ -450,7 +418,6 @@ float MaxPlayer(const GTNode* node)
{
return GetScore(node->mState);
}
-
float maxValue = -std::numeric_limits::infinity();
// Find the subtree with the maximum value
for (const GTNode* child : node->mChildren)
@@ -467,7 +434,6 @@ float MinPlayer(const GTNode* node)
{
return GetScore(node->mState);
}
-
float minValue = std::numeric_limits::infinity();
// Find the subtree with the minimum value
for (const GTNode* child : node->mChildren)
@@ -482,7 +448,7 @@ const GTNode* MinimaxDecide(const GTNode* root)
// Find the subtree with the maximum value, and save the choice
const GTNode* choice = nullptr;
float maxValue = -std::numeric_limits::infinity();
- for (const GTNode* child : root->mChildren)
+ for (const GTNode* child: root->mChildren)
{
float v = MinPlayer(child);
if (v > maxValue)
@@ -503,7 +469,6 @@ float AlphaBetaMax(const GTNode* node, float alpha, float beta)
{
return GetScore(node->mState);
}
-
float maxValue = -std::numeric_limits::infinity();
// Find the subtree with the maximum value
for (const GTNode* child : node->mChildren)
@@ -525,7 +490,6 @@ float AlphaBetaMin(const GTNode* node, float alpha, float beta)
{
return GetScore(node->mState);
}
-
float minValue = std::numeric_limits::infinity();
// Find the subtree with the minimum value
for (const GTNode* child : node->mChildren)
@@ -570,8 +534,7 @@ void testTicTac()
root->mState.mBoard[2][0] = GameState::X;
root->mState.mBoard[2][1] = GameState::Empty;
root->mState.mBoard[2][2] = GameState::Empty;
-
GenStates(root, true);
const GTNode* choice = AlphaBetaDecide(root);
std::cout << choice->mChildren.size();
-}
+}
\ No newline at end of file
diff --git a/Chapter04/SpriteComponent.cpp b/Chapter04/SpriteComponent.cpp
index 56884fbc..e661e423 100644
--- a/Chapter04/SpriteComponent.cpp
+++ b/Chapter04/SpriteComponent.cpp
@@ -10,47 +10,35 @@
#include "Actor.h"
#include "Game.h"
-SpriteComponent::SpriteComponent(Actor* owner, int drawOrder)
- :Component(owner)
- ,mTexture(nullptr)
- ,mDrawOrder(drawOrder)
- ,mTexWidth(0)
- ,mTexHeight(0)
+SpriteComponent::SpriteComponent(Actor* owner, int drawOrder): Component(owner), pTexture(nullptr), mDrawOrder(drawOrder), mTexWidth(0), mTexHeight(0)
{
- mOwner->GetGame()->AddSprite(this);
+ pOwner->GetGame()->AddSprite(this);
}
SpriteComponent::~SpriteComponent()
{
- mOwner->GetGame()->RemoveSprite(this);
+ pOwner->GetGame()->RemoveSprite(this);
}
void SpriteComponent::Draw(SDL_Renderer* renderer)
{
- if (mTexture)
+ if (pTexture)
{
SDL_Rect r;
// Scale the width/height by owner's scale
- r.w = static_cast(mTexWidth * mOwner->GetScale());
- r.h = static_cast(mTexHeight * mOwner->GetScale());
+ r.w = static_cast(mTexWidth * pOwner->GetScale());
+ r.h = static_cast(mTexHeight * pOwner->GetScale());
// Center the rectangle around the position of the owner
- r.x = static_cast(mOwner->GetPosition().x - r.w / 2);
- r.y = static_cast(mOwner->GetPosition().y - r.h / 2);
-
+ r.x = static_cast(pOwner->GetPosition().x - r.w / 2);
+ r.y = static_cast(pOwner->GetPosition().y - r.h / 2);
// Draw (have to convert angle from radians to degrees, and clockwise to counter)
- SDL_RenderCopyEx(renderer,
- mTexture,
- nullptr,
- &r,
- -Math::ToDegrees(mOwner->GetRotation()),
- nullptr,
- SDL_FLIP_NONE);
+ SDL_RenderCopyEx(renderer, pTexture, nullptr, &r, -Math::ToDegrees(pOwner->GetRotation()), nullptr, SDL_FLIP_NONE);
}
}
void SpriteComponent::SetTexture(SDL_Texture* texture)
{
- mTexture = texture;
+ pTexture = texture;
// Set width/height
SDL_QueryTexture(texture, nullptr, nullptr, &mTexWidth, &mTexHeight);
-}
+}
\ No newline at end of file
diff --git a/Chapter04/SpriteComponent.h b/Chapter04/SpriteComponent.h
index c430e888..70357ba9 100644
--- a/Chapter04/SpriteComponent.h
+++ b/Chapter04/SpriteComponent.h
@@ -9,22 +9,20 @@
#pragma once
#include "Component.h"
#include "SDL/SDL.h"
-class SpriteComponent : public Component
+class SpriteComponent: public Component
{
public:
// (Lower draw order corresponds with further back)
SpriteComponent(class Actor* owner, int drawOrder = 100);
~SpriteComponent();
-
virtual void Draw(SDL_Renderer* renderer);
virtual void SetTexture(SDL_Texture* texture);
-
int GetDrawOrder() const { return mDrawOrder; }
int GetTexHeight() const { return mTexHeight; }
int GetTexWidth() const { return mTexWidth; }
protected:
- SDL_Texture* mTexture;
+ SDL_Texture* pTexture;
int mDrawOrder;
int mTexWidth;
int mTexHeight;
-};
+};
\ No newline at end of file
diff --git a/Chapter04/Tile.cpp b/Chapter04/Tile.cpp
index 90e5c781..57c34b64 100644
--- a/Chapter04/Tile.cpp
+++ b/Chapter04/Tile.cpp
@@ -10,18 +10,9 @@
#include "SpriteComponent.h"
#include "Game.h"
-Tile::Tile(class Game* game)
-:Actor(game)
-,mParent(nullptr)
-,f(0.0f)
-,g(0.0f)
-,h(0.0f)
-,mBlocked(false)
-,mSprite(nullptr)
-,mTileState(EDefault)
-,mSelected(false)
+Tile::Tile(class Game* game): Actor(game), mParent(nullptr), mF(0.0f), mG(0.0f), mH(0.0f), mBlocked(false), pSprite(nullptr), mTileState(EDefault), mSelected(false)
{
- mSprite = new SpriteComponent(this);
+ pSprite = new SpriteComponent(this);
UpdateTexture();
}
@@ -62,5 +53,5 @@ void Tile::UpdateTexture()
text = "Assets/TileBrown.png";
break;
}
- mSprite->SetTexture(GetGame()->GetTexture(text));
-}
+ pSprite->SetTexture(GetGame()->GetTexture(text));
+}
\ No newline at end of file
diff --git a/Chapter04/Tile.h b/Chapter04/Tile.h
index f3e90d12..0281de90 100644
--- a/Chapter04/Tile.h
+++ b/Chapter04/Tile.h
@@ -10,7 +10,7 @@
#include "Actor.h"
#include
-class Tile : public Actor
+class Tile: public Actor
{
public:
friend class Grid;
@@ -21,9 +21,7 @@ class Tile : public Actor
EStart,
EBase
};
-
Tile(class Game* game);
-
void SetTileState(TileState state);
TileState GetTileState() const { return mTileState; }
void ToggleSelect();
@@ -32,15 +30,14 @@ class Tile : public Actor
// For pathfinding
std::vector mAdjacent;
Tile* mParent;
- float f;
- float g;
- float h;
+ float mF;
+ float mG;
+ float mH;
bool mInOpenSet;
bool mInClosedSet;
bool mBlocked;
-
void UpdateTexture();
- class SpriteComponent* mSprite;
+ class SpriteComponent* pSprite;
TileState mTileState;
bool mSelected;
-};
+};
\ No newline at end of file
diff --git a/Chapter04/Tower.cpp b/Chapter04/Tower.cpp
index 20d60dea..c8493b46 100644
--- a/Chapter04/Tower.cpp
+++ b/Chapter04/Tower.cpp
@@ -12,29 +12,31 @@
#include "Game.h"
#include "Enemy.h"
#include "Bullet.h"
+#include "AIState.h"
-Tower::Tower(class Game* game)
-:Actor(game)
+Tower::Tower(class Game* game): Actor(game)
{
SpriteComponent* sc = new SpriteComponent(this, 200);
sc->SetTexture(game->GetTexture("Assets/Tower.png"));
-
- mMove = new MoveComponent(this);
- //mMove->SetAngularSpeed(Math::Pi);
-
+ pMove = new MoveComponent(this);
+ //pMove->SetAngularSpeed(Math::Pi);
+ pAI = new AIComponent(this);
+ pAI->RegisterState(new AIPatrol(pAI));
+ pAI->RegisterState(new AIAttack(pAI));
+ pAI->ChangeState("Patrol");
mNextAttack = AttackTime;
}
void Tower::UpdateActor(float deltaTime)
{
Actor::UpdateActor(deltaTime);
-
mNextAttack -= deltaTime;
if (mNextAttack <= 0.0f)
{
Enemy* e = GetGame()->GetNearestEnemy(GetPosition());
if (e != nullptr)
{
+ pAI->ChangeState("Attack");
// Vector from me to enemy
Vector2 dir = e->GetPosition() - GetPosition();
float dist = dir.Length();
@@ -48,6 +50,10 @@ void Tower::UpdateActor(float deltaTime)
b->SetRotation(GetRotation());
}
}
+ else
+ {
+ pAI->ChangeState("Patrol");
+ }
mNextAttack += AttackTime;
}
-}
+}
\ No newline at end of file
diff --git a/Chapter04/Tower.h b/Chapter04/Tower.h
index bfbf12ff..67365bfd 100644
--- a/Chapter04/Tower.h
+++ b/Chapter04/Tower.h
@@ -8,15 +8,17 @@
#pragma once
#include "Actor.h"
+#include "AIComponent.h"
-class Tower : public Actor
+class Tower: public Actor
{
public:
Tower(class Game* game);
void UpdateActor(float deltaTime) override;
private:
- class MoveComponent* mMove;
+ class MoveComponent* pMove;
+ class AIComponent* pAI;
float mNextAttack;
const float AttackTime = 2.5f;
const float AttackRange = 100.0f;
-};
+};
\ No newline at end of file
diff --git a/Chapter05/Actor.cpp b/Chapter05/Actor.cpp
index 738d508f..494f52ec 100644
--- a/Chapter05/Actor.cpp
+++ b/Chapter05/Actor.cpp
@@ -11,20 +11,14 @@
#include "Component.h"
#include
-Actor::Actor(Game* game)
- :mState(EActive)
- ,mPosition(Vector2::Zero)
- ,mScale(1.0f)
- ,mRotation(0.0f)
- ,mGame(game)
- ,mRecomputeWorldTransform(true)
+Actor::Actor(Game* game): mState(EActive), mPosition(Vector2::Zero), mScale(1.0f), mRotation(0.0f), pGame(game), mRecomputeWorldTransform(true)
{
- mGame->AddActor(this);
+ pGame->AddActor(this);
}
Actor::~Actor()
{
- mGame->RemoveActor(this);
+ pGame->RemoveActor(this);
// Need to delete components
// Because ~Component calls RemoveComponent, need a different style loop
while (!mComponents.empty())
@@ -38,10 +32,8 @@ void Actor::Update(float deltaTime)
if (mState == EActive)
{
ComputeWorldTransform();
-
UpdateComponents(deltaTime);
UpdateActor(deltaTime);
-
ComputeWorldTransform();
}
}
@@ -67,7 +59,6 @@ void Actor::ProcessInput(const uint8_t* keyState)
{
comp->ProcessInput(keyState);
}
-
ActorInput(keyState);
}
}
@@ -85,7 +76,6 @@ void Actor::ComputeWorldTransform()
mWorldTransform = Matrix4::CreateScale(mScale);
mWorldTransform *= Matrix4::CreateRotationZ(mRotation);
mWorldTransform *= Matrix4::CreateTranslation(Vector3(mPosition.x, mPosition.y, 0.0f));
-
// Inform components world transform updated
for (auto comp : mComponents)
{
@@ -100,16 +90,13 @@ void Actor::AddComponent(Component* component)
// (The first element with a order higher than me)
int myOrder = component->GetUpdateOrder();
auto iter = mComponents.begin();
- for (;
- iter != mComponents.end();
- ++iter)
+ for (; iter != mComponents.end(); ++iter)
{
if (myOrder < (*iter)->GetUpdateOrder())
{
break;
}
}
-
// Inserts element before position of iterator
mComponents.insert(iter, component);
}
@@ -121,4 +108,4 @@ void Actor::RemoveComponent(Component* component)
{
mComponents.erase(iter);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Actor.h b/Chapter05/Actor.h
index 7a41bd47..fee90714 100644
--- a/Chapter05/Actor.h
+++ b/Chapter05/Actor.h
@@ -20,22 +20,18 @@ class Actor
EPaused,
EDead
};
-
Actor(class Game* game);
virtual ~Actor();
-
// Update function called from Game (not overridable)
void Update(float deltaTime);
// Updates all the components attached to the actor (not overridable)
void UpdateComponents(float deltaTime);
// Any actor-specific update code (overridable)
virtual void UpdateActor(float deltaTime);
-
// ProcessInput function called from Game (not overridable)
void ProcessInput(const uint8_t* keyState);
// Any actor-specific input code (overridable)
virtual void ActorInput(const uint8_t* keyState);
-
// Getters/setters
const Vector2& GetPosition() const { return mPosition; }
void SetPosition(const Vector2& pos) { mPosition = pos; mRecomputeWorldTransform = true; }
@@ -43,32 +39,24 @@ class Actor
void SetScale(float scale) { mScale = scale; mRecomputeWorldTransform = true; }
float GetRotation() const { return mRotation; }
void SetRotation(float rotation) { mRotation = rotation; mRecomputeWorldTransform = true; }
-
void ComputeWorldTransform();
const Matrix4& GetWorldTransform() const { return mWorldTransform; }
-
Vector2 GetForward() const { return Vector2(Math::Cos(mRotation), Math::Sin(mRotation)); }
-
State GetState() const { return mState; }
void SetState(State state) { mState = state; }
-
- class Game* GetGame() { return mGame; }
-
-
+ class Game* GetGame() { return pGame; }
// Add/remove components
void AddComponent(class Component* component);
void RemoveComponent(class Component* component);
private:
// Actor's state
State mState;
-
// Transform
Matrix4 mWorldTransform;
Vector2 mPosition;
float mScale;
float mRotation;
bool mRecomputeWorldTransform;
-
std::vector mComponents;
- class Game* mGame;
+ class Game* pGame;
};
diff --git a/Chapter05/Asteroid.cpp b/Chapter05/Asteroid.cpp
index 9bcaa1e1..098c6607 100644
--- a/Chapter05/Asteroid.cpp
+++ b/Chapter05/Asteroid.cpp
@@ -13,29 +13,21 @@
#include "Random.h"
#include "CircleComponent.h"
-Asteroid::Asteroid(Game* game)
- :Actor(game)
- ,mCircle(nullptr)
+Asteroid::Asteroid(Game* game): Actor(game), pCircle(nullptr)
{
// Initialize to random position/orientation
- Vector2 randPos = Random::GetVector(Vector2(-512.0f, -384.0f),
- Vector2(512.0f, 384.0f));
+ Vector2 randPos = Random::GetVector(Vector2(-512.0f, -384.0f), Vector2(512.0f, 384.0f));
SetPosition(randPos);
-
SetRotation(Random::GetFloatRange(0.0f, Math::TwoPi));
-
// Create a sprite component
SpriteComponent* sc = new SpriteComponent(this);
sc->SetTexture(game->GetTexture("Assets/Asteroid.png"));
-
// Create a move component, and set a forward speed
MoveComponent* mc = new MoveComponent(this);
mc->SetForwardSpeed(150.0f);
-
// Create a circle component (for collision)
- mCircle = new CircleComponent(this);
- mCircle->SetRadius(40.0f);
-
+ pCircle = new CircleComponent(this);
+ pCircle->SetRadius(40.0f);
// Add to mAsteroids in game
game->AddAsteroid(this);
}
@@ -43,4 +35,4 @@ Asteroid::Asteroid(Game* game)
Asteroid::~Asteroid()
{
GetGame()->RemoveAsteroid(this);
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Asteroid.h b/Chapter05/Asteroid.h
index 45305770..fd64416a 100644
--- a/Chapter05/Asteroid.h
+++ b/Chapter05/Asteroid.h
@@ -8,13 +8,12 @@
#pragma once
#include "Actor.h"
-class Asteroid : public Actor
+class Asteroid: public Actor
{
public:
Asteroid(class Game* game);
~Asteroid();
-
- class CircleComponent* GetCircle() { return mCircle; }
+ class CircleComponent* GetCircle() { return pCircle; }
private:
- class CircleComponent* mCircle;
-};
+ class CircleComponent* pCircle;
+};
\ No newline at end of file
diff --git a/Chapter05/CircleComponent.cpp b/Chapter05/CircleComponent.cpp
index d41aab2c..e0e31b71 100644
--- a/Chapter05/CircleComponent.cpp
+++ b/Chapter05/CircleComponent.cpp
@@ -9,21 +9,18 @@
#include "CircleComponent.h"
#include "Actor.h"
-CircleComponent::CircleComponent(class Actor* owner)
-:Component(owner)
-,mRadius(0.0f)
+CircleComponent::CircleComponent(class Actor* owner): Component(owner), mRadius(0.0f)
{
-
}
const Vector2& CircleComponent::GetCenter() const
{
- return mOwner->GetPosition();
+ return pOwner->GetPosition();
}
float CircleComponent::GetRadius() const
{
- return mOwner->GetScale() * mRadius;
+ return pOwner->GetScale() * mRadius;
}
bool Intersect(const CircleComponent& a, const CircleComponent& b)
@@ -31,10 +28,8 @@ bool Intersect(const CircleComponent& a, const CircleComponent& b)
// Calculate distance squared
Vector2 diff = a.GetCenter() - b.GetCenter();
float distSq = diff.LengthSq();
-
// Calculate sum of radii squared
float radiiSq = a.GetRadius() + b.GetRadius();
radiiSq *= radiiSq;
-
return distSq <= radiiSq;
-}
+}
\ No newline at end of file
diff --git a/Chapter05/CircleComponent.h b/Chapter05/CircleComponent.h
index 4eecb2a4..113bd5e5 100644
--- a/Chapter05/CircleComponent.h
+++ b/Chapter05/CircleComponent.h
@@ -10,17 +10,15 @@
#include "Component.h"
#include "Math.h"
-class CircleComponent : public Component
+class CircleComponent: public Component
{
public:
CircleComponent(class Actor* owner);
-
void SetRadius(float radius) { mRadius = radius; }
float GetRadius() const;
-
const Vector2& GetCenter() const;
private:
float mRadius;
};
-bool Intersect(const CircleComponent& a, const CircleComponent& b);
+bool Intersect(const CircleComponent& a, const CircleComponent& b);
\ No newline at end of file
diff --git a/Chapter05/Component.cpp b/Chapter05/Component.cpp
index c4ed432d..5446d684 100644
--- a/Chapter05/Component.cpp
+++ b/Chapter05/Component.cpp
@@ -9,19 +9,17 @@
#include "Component.h"
#include "Actor.h"
-Component::Component(Actor* owner, int updateOrder)
- :mOwner(owner)
- ,mUpdateOrder(updateOrder)
+Component::Component(Actor* owner, int updateOrder): pOwner(owner), mUpdateOrder(updateOrder)
{
// Add to actor's vector of components
- mOwner->AddComponent(this);
+ pOwner->AddComponent(this);
}
Component::~Component()
{
- mOwner->RemoveComponent(this);
+ pOwner->RemoveComponent(this);
}
void Component::Update(float deltaTime)
{
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Component.h b/Chapter05/Component.h
index e2be424b..a72aa198 100644
--- a/Chapter05/Component.h
+++ b/Chapter05/Component.h
@@ -12,8 +12,7 @@
class Component
{
public:
- // Constructor
- // (the lower the update order, the earlier the component updates)
+ // Constructor (the lower the update order, the earlier the component updates)
Component(class Actor* owner, int updateOrder = 100);
// Destructor
virtual ~Component();
@@ -23,11 +22,10 @@ class Component
virtual void ProcessInput(const uint8_t* keyState) {}
// Called when world transform changes
virtual void OnUpdateWorldTransform() { }
-
int GetUpdateOrder() const { return mUpdateOrder; }
protected:
// Owning actor
- class Actor* mOwner;
+ class Actor* pOwner;
// Update order of component
int mUpdateOrder;
-};
+};
\ No newline at end of file
diff --git a/Chapter05/Game.cpp b/Chapter05/Game.cpp
index e18e90a3..57cf7e5b 100644
--- a/Chapter05/Game.cpp
+++ b/Chapter05/Game.cpp
@@ -19,13 +19,8 @@
#include "Asteroid.h"
#include "Random.h"
-Game::Game()
-:mWindow(nullptr)
-,mSpriteShader(nullptr)
-,mIsRunning(true)
-,mUpdatingActors(false)
+Game::Game(): pWindow(nullptr), pSpriteShader(nullptr), mIsRunning(true), mUpdatingActors(false), mBGColor(Color::Black), mBGDirection(true)
{
-
}
bool Game::Initialize()
@@ -35,8 +30,7 @@ bool Game::Initialize()
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
return false;
}
-
- // Set OpenGL attributes
+// Set OpenGL attributes:
// Use the core OpenGL profile
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
// Specify version 3.3
@@ -51,18 +45,14 @@ bool Game::Initialize()
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// Force OpenGL to use hardware acceleration
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
-
- mWindow = SDL_CreateWindow("Game Programming in C++ (Chapter 5)", 100, 100,
- 1024, 768, SDL_WINDOW_OPENGL);
- if (!mWindow)
+ pWindow = SDL_CreateWindow("Game Programming in C++ (Chapter 5)", 100, 100, 1024, 768, SDL_WINDOW_OPENGL);
+ if (!pWindow)
{
SDL_Log("Failed to create window: %s", SDL_GetError());
return false;
}
-
// Create an OpenGL context
- mContext = SDL_GL_CreateContext(mWindow);
-
+ mContext = SDL_GL_CreateContext(pWindow);
// Initialize GLEW
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
@@ -70,25 +60,18 @@ bool Game::Initialize()
SDL_Log("Failed to initialize GLEW.");
return false;
}
-
- // On some platforms, GLEW will emit a benign error code,
- // so clear it
+ // On some platforms, GLEW will emit a benign error code, so clear it
glGetError();
-
// Make sure we can create/compile shaders
if (!LoadShaders())
{
SDL_Log("Failed to load shaders.");
return false;
}
-
// Create quad for drawing sprites
CreateSpriteVerts();
-
LoadData();
-
mTicksCount = SDL_GetTicks();
-
return true;
}
@@ -98,7 +81,7 @@ void Game::RunLoop()
{
ProcessInput();
UpdateGame();
- GenerateOutput();
+ //GenerateOutput();
}
}
@@ -114,15 +97,13 @@ void Game::ProcessInput()
break;
}
}
-
const Uint8* keyState = SDL_GetKeyboardState(NULL);
if (keyState[SDL_SCANCODE_ESCAPE])
{
mIsRunning = false;
}
-
mUpdatingActors = true;
- for (auto actor : mActors)
+ for (auto actor: mActors)
{
actor->ProcessInput(keyState);
}
@@ -133,24 +114,20 @@ void Game::UpdateGame()
{
// Compute delta time
// Wait until 16ms has elapsed since last frame
- while (!SDL_TICKS_PASSED(SDL_GetTicks(), mTicksCount + 16))
- ;
-
+ while (!SDL_TICKS_PASSED(SDL_GetTicks(), mTicksCount + 16));
float deltaTime = (SDL_GetTicks() - mTicksCount) / 1000.0f;
if (deltaTime > 0.05f)
{
deltaTime = 0.05f;
}
mTicksCount = SDL_GetTicks();
-
- // Update all actors
+// Update all actors:
mUpdatingActors = true;
for (auto actor : mActors)
{
actor->Update(deltaTime);
}
mUpdatingActors = false;
-
// Move any pending actors to mActors
for (auto pending : mPendingActors)
{
@@ -158,7 +135,6 @@ void Game::UpdateGame()
mActors.emplace_back(pending);
}
mPendingActors.clear();
-
// Add any dead actors to a temp vector
std::vector deadActors;
for (auto actor : mActors)
@@ -168,76 +144,84 @@ void Game::UpdateGame()
deadActors.emplace_back(actor);
}
}
-
// Delete dead actors (which removes them from mActors)
for (auto actor : deadActors)
{
delete actor;
}
+ GenerateOutput(deltaTime);
}
-void Game::GenerateOutput()
+void Game::GenerateOutput(float deltaTime)
{
- // Set the clear color to grey
- glClearColor(0.86f, 0.86f, 0.86f, 1.0f);
+ if (mBGDirection && (mBGColor.z < Color::Blue.z))
+ {
+ // Update the current background color
+ mBGColor.z += 0.1f * deltaTime;
+ }
+ else if (!mBGDirection && (mBGColor.z > Color::Black.z))
+ {
+ // Update the current background color
+ mBGColor.z -= 0.1f * deltaTime;
+ }
+ else
+ {
+ mBGDirection = !mBGDirection;
+ }
+ // Set the clear color to the current background color
+ glClearColor(mBGColor.x, mBGColor.y, mBGColor.z, 1.0f);
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
-
// Draw all sprite components
// Enable alpha blending on the color buffer
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
// Set shader/vao as active
- mSpriteShader->SetActive();
- mSpriteVerts->SetActive();
- for (auto sprite : mSprites)
+ pSpriteShader->SetActive();
+ pSpriteVerts->SetActive();
+ for (auto sprite: mSprites)
{
- sprite->Draw(mSpriteShader);
+ sprite->Draw(pSpriteShader);
}
-
// Swap the buffers
- SDL_GL_SwapWindow(mWindow);
+ SDL_GL_SwapWindow(pWindow);
}
bool Game::LoadShaders()
{
- mSpriteShader = new Shader();
- if (!mSpriteShader->Load("Shaders/Sprite.vert", "Shaders/Sprite.frag"))
+ pSpriteShader = new Shader();
+ if (!pSpriteShader->Load("Shaders/Sprite.vert", "Shaders/Sprite.frag"))
{
return false;
}
-
- mSpriteShader->SetActive();
+ pSpriteShader->SetActive();
// Set the view-projection matrix
Matrix4 viewProj = Matrix4::CreateSimpleViewProj(1024.f, 768.f);
- mSpriteShader->SetMatrixUniform("uViewProj", viewProj);
+ pSpriteShader->SetMatrixUniform("uViewProj", viewProj);
return true;
}
void Game::CreateSpriteVerts()
{
+ // Position (3), Texture coordinates(2), Vertex color(3)
float vertices[] = {
- -0.5f, 0.5f, 0.f, 0.f, 0.f, // top left
- 0.5f, 0.5f, 0.f, 1.f, 0.f, // top right
- 0.5f, -0.5f, 0.f, 1.f, 1.f, // bottom right
- -0.5f, -0.5f, 0.f, 0.f, 1.f // bottom left
+ -0.5f, 0.5f, 0.f, 0.f, 0.f, 1.0f, 0.0f, 0.0f, // top left
+ 0.5f, 0.5f, 0.f, 1.f, 0.f, 0.0f, 1.0f, 0.0f, // top right
+ 0.5f, -0.5f, 0.f, 1.f, 1.f, 1.0f, 1.0f, 0.0f, // bottom right
+ -0.5f, -0.5f, 0.f, 0.f, 1.f, 0.0f, 1.0f, 1.0f, // bottom left
};
-
unsigned int indices[] = {
0, 1, 2,
2, 3, 0
};
-
- mSpriteVerts = new VertexArray(vertices, 4, indices, 6);
+ pSpriteVerts = new VertexArray(vertices, 8, 4, indices, 6);
}
void Game::LoadData()
{
// Create player's ship
- mShip = new Ship(this);
- mShip->SetRotation(Math::PiOver2);
-
+ pShip = new Ship(this);
+ pShip->SetRotation(Math::PiOver2);
// Create asteroids
const int numAsteroids = 20;
for (int i = 0; i < numAsteroids; i++)
@@ -254,7 +238,6 @@ void Game::UnloadData()
{
delete mActors.back();
}
-
// Destroy textures
for (auto i : mTextures)
{
@@ -295,8 +278,7 @@ void Game::AddAsteroid(Asteroid* ast)
void Game::RemoveAsteroid(Asteroid* ast)
{
- auto iter = std::find(mAsteroids.begin(),
- mAsteroids.end(), ast);
+ auto iter = std::find(mAsteroids.begin(), mAsteroids.end(), ast);
if (iter != mAsteroids.end())
{
mAsteroids.erase(iter);
@@ -306,11 +288,11 @@ void Game::RemoveAsteroid(Asteroid* ast)
void Game::Shutdown()
{
UnloadData();
- delete mSpriteVerts;
- mSpriteShader->Unload();
- delete mSpriteShader;
+ delete pSpriteVerts;
+ pSpriteShader->Unload();
+ delete pSpriteShader;
SDL_GL_DeleteContext(mContext);
- SDL_DestroyWindow(mWindow);
+ SDL_DestroyWindow(pWindow);
SDL_Quit();
}
@@ -337,7 +319,6 @@ void Game::RemoveActor(Actor* actor)
std::iter_swap(iter, mPendingActors.end() - 1);
mPendingActors.pop_back();
}
-
// Is it in actors?
iter = std::find(mActors.begin(), mActors.end(), actor);
if (iter != mActors.end())
@@ -354,16 +335,13 @@ void Game::AddSprite(SpriteComponent* sprite)
// (The first element with a higher draw order than me)
int myDrawOrder = sprite->GetDrawOrder();
auto iter = mSprites.begin();
- for (;
- iter != mSprites.end();
- ++iter)
+ for (; iter != mSprites.end(); ++iter)
{
if (myDrawOrder < (*iter)->GetDrawOrder())
{
break;
}
}
-
// Inserts element before position of iterator
mSprites.insert(iter, sprite);
}
@@ -372,4 +350,4 @@ void Game::RemoveSprite(SpriteComponent* sprite)
{
auto iter = std::find(mSprites.begin(), mSprites.end(), sprite);
mSprites.erase(iter);
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Game.h b/Chapter05/Game.h
index d5c22637..fe695626 100644
--- a/Chapter05/Game.h
+++ b/Chapter05/Game.h
@@ -20,15 +20,11 @@ class Game
bool Initialize();
void RunLoop();
void Shutdown();
-
void AddActor(class Actor* actor);
void RemoveActor(class Actor* actor);
-
void AddSprite(class SpriteComponent* sprite);
void RemoveSprite(class SpriteComponent* sprite);
-
class Texture* GetTexture(const std::string& fileName);
-
// Game-specific (add/remove asteroid)
void AddAsteroid(class Asteroid* ast);
void RemoveAsteroid(class Asteroid* ast);
@@ -36,36 +32,33 @@ class Game
private:
void ProcessInput();
void UpdateGame();
- void GenerateOutput();
+ void GenerateOutput(float deltaTime);
bool LoadShaders();
void CreateSpriteVerts();
void LoadData();
void UnloadData();
-
+
// Map of textures loaded
std::unordered_map mTextures;
-
// All the actors in the game
std::vector mActors;
// Any pending actors
std::vector mPendingActors;
-
// All the sprite components drawn
std::vector mSprites;
-
// Sprite shader
- class Shader* mSpriteShader;
+ class Shader* pSpriteShader;
// Sprite vertex array
- class VertexArray* mSpriteVerts;
-
- SDL_Window* mWindow;
+ class VertexArray* pSpriteVerts;
+ SDL_Window* pWindow;
SDL_GLContext mContext;
Uint32 mTicksCount;
bool mIsRunning;
// Track if we're updating actors right now
bool mUpdatingActors;
-
// Game-specific
- class Ship* mShip;
+ class Ship* pShip;
std::vector mAsteroids;
-};
+ Vector3 mBGColor;
+ bool mBGDirection;
+};
\ No newline at end of file
diff --git a/Chapter05/Game.vcxproj b/Chapter05/Game.vcxproj
index b0bd2f45..15c0a42b 100644
--- a/Chapter05/Game.vcxproj
+++ b/Chapter05/Game.vcxproj
@@ -56,19 +56,19 @@
{BC508D87-495F-4554-932D-DD68388B63CC}
Win32Proj
Game
- 10.0.16299.0
+ 10.0
Application
true
- v141
+ v143
Unicode
Application
false
- v141
+ v143
true
Unicode
diff --git a/Chapter05/InputComponent.cpp b/Chapter05/InputComponent.cpp
index 148ffc95..1e5acfbd 100644
--- a/Chapter05/InputComponent.cpp
+++ b/Chapter05/InputComponent.cpp
@@ -9,14 +9,8 @@
#include "InputComponent.h"
#include "Actor.h"
-InputComponent::InputComponent(class Actor* owner)
-:MoveComponent(owner)
-,mForwardKey(0)
-,mBackKey(0)
-,mClockwiseKey(0)
-,mCounterClockwiseKey(0)
-{
-
+InputComponent::InputComponent(class Actor* owner): MoveComponent(owner), mForwardKey(0), mBackKey(0), mClockwiseKey(0), mCounterClockwiseKey(0)
+{
}
void InputComponent::ProcessInput(const uint8_t* keyState)
@@ -32,7 +26,6 @@ void InputComponent::ProcessInput(const uint8_t* keyState)
forwardSpeed -= mMaxForwardSpeed;
}
SetForwardSpeed(forwardSpeed);
-
// Calculate angular speed for MoveComponent
float angularSpeed = 0.0f;
if (keyState[mClockwiseKey])
@@ -44,4 +37,4 @@ void InputComponent::ProcessInput(const uint8_t* keyState)
angularSpeed -= mMaxAngularSpeed;
}
SetAngularSpeed(angularSpeed);
-}
+}
\ No newline at end of file
diff --git a/Chapter05/InputComponent.h b/Chapter05/InputComponent.h
index 57b32ccb..163f85ee 100644
--- a/Chapter05/InputComponent.h
+++ b/Chapter05/InputComponent.h
@@ -10,14 +10,12 @@
#include "MoveComponent.h"
#include
-class InputComponent : public MoveComponent
+class InputComponent: public MoveComponent
{
public:
// Lower update order to update first
InputComponent(class Actor* owner);
-
void ProcessInput(const uint8_t* keyState) override;
-
// Getters/setters for private variables
float GetMaxForward() const { return mMaxForwardSpeed; }
float GetMaxAngular() const { return mMaxAngularSpeed; }
@@ -25,7 +23,6 @@ class InputComponent : public MoveComponent
int GetBackKey() const { return mBackKey; }
int GetClockwiseKey() const { return mClockwiseKey; }
int GetCounterClockwiseKey() const { return mCounterClockwiseKey; }
-
void SetMaxForwardSpeed(float speed) { mMaxForwardSpeed = speed; }
void SetMaxAngularSpeed(float speed) { mMaxAngularSpeed = speed; }
void SetForwardKey(int key) { mForwardKey = key; }
@@ -42,4 +39,4 @@ class InputComponent : public MoveComponent
// Keys for angular movement
int mClockwiseKey;
int mCounterClockwiseKey;
-};
+};
\ No newline at end of file
diff --git a/Chapter05/Laser.cpp b/Chapter05/Laser.cpp
index a03c1981..9a1a7d71 100644
--- a/Chapter05/Laser.cpp
+++ b/Chapter05/Laser.cpp
@@ -13,21 +13,17 @@
#include "CircleComponent.h"
#include "Asteroid.h"
-Laser::Laser(Game* game)
- :Actor(game)
- ,mDeathTimer(1.0f)
+Laser::Laser(Game* game): Actor(game), mDeathTimer(1.0f)
{
// Create a sprite component
SpriteComponent* sc = new SpriteComponent(this);
sc->SetTexture(game->GetTexture("Assets/Laser.png"));
-
// Create a move component, and set a forward speed
MoveComponent* mc = new MoveComponent(this);
mc->SetForwardSpeed(800.0f);
-
// Create a circle component (for collision)
- mCircle = new CircleComponent(this);
- mCircle->SetRadius(11.0f);
+ pCircle = new CircleComponent(this);
+ pCircle->SetRadius(11.0f);
}
void Laser::UpdateActor(float deltaTime)
@@ -41,9 +37,9 @@ void Laser::UpdateActor(float deltaTime)
else
{
// Do we intersect with an asteroid?
- for (auto ast : GetGame()->GetAsteroids())
+ for (auto ast: GetGame()->GetAsteroids())
{
- if (Intersect(*mCircle, *(ast->GetCircle())))
+ if (Intersect(*pCircle, *(ast->GetCircle())))
{
// The first asteroid we intersect with,
// set ourselves and the asteroid to dead
@@ -53,4 +49,4 @@ void Laser::UpdateActor(float deltaTime)
}
}
}
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Laser.h b/Chapter05/Laser.h
index f1afd638..c995e91e 100644
--- a/Chapter05/Laser.h
+++ b/Chapter05/Laser.h
@@ -8,13 +8,12 @@
#pragma once
#include "Actor.h"
-class Laser : public Actor
+class Laser: public Actor
{
public:
Laser(class Game* game);
-
void UpdateActor(float deltaTime) override;
private:
- class CircleComponent* mCircle;
+ class CircleComponent* pCircle;
float mDeathTimer;
-};
+};
\ No newline at end of file
diff --git a/Chapter05/Main.cpp b/Chapter05/Main.cpp
index 22ea0c69..625e0599 100644
--- a/Chapter05/Main.cpp
+++ b/Chapter05/Main.cpp
@@ -18,4 +18,4 @@ int main(int argc, char** argv)
}
game.Shutdown();
return 0;
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Math.cpp b/Chapter05/Math.cpp
index a16e7261..44ff7ddd 100644
--- a/Chapter05/Math.cpp
+++ b/Chapter05/Math.cpp
@@ -39,7 +39,6 @@ static float m4Ident[4][4] =
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
};
-
const Matrix4 Matrix4::Identity(m4Ident);
const Quaternion Quaternion::Identity(0.0f, 0.0f, 0.0f, 1.0f);
@@ -104,33 +103,28 @@ void Matrix4::Invert()
float src[16];
float dst[16];
float det;
-
- // Transpose matrix
+// Transpose matrix:
// row 1 to col 1
src[0] = mat[0][0];
src[4] = mat[0][1];
src[8] = mat[0][2];
src[12] = mat[0][3];
-
// row 2 to col 2
src[1] = mat[1][0];
src[5] = mat[1][1];
src[9] = mat[1][2];
src[13] = mat[1][3];
-
// row 3 to col 3
src[2] = mat[2][0];
src[6] = mat[2][1];
src[10] = mat[2][2];
src[14] = mat[2][3];
-
// row 4 to col 4
src[3] = mat[3][0];
src[7] = mat[3][1];
src[11] = mat[3][2];
src[15] = mat[3][3];
-
- // Calculate cofactors
+// Calculate cofactors:
tmp[0] = src[10] * src[15];
tmp[1] = src[11] * src[14];
tmp[2] = src[9] * src[15];
@@ -143,7 +137,6 @@ void Matrix4::Invert()
tmp[9] = src[10] * src[12];
tmp[10] = src[8] * src[13];
tmp[11] = src[9] * src[12];
-
dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7];
dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7];
dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7];
@@ -160,7 +153,6 @@ void Matrix4::Invert()
dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3];
dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2];
dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2];
-
tmp[0] = src[2] * src[7];
tmp[1] = src[3] * src[6];
tmp[2] = src[1] * src[7];
@@ -173,7 +165,6 @@ void Matrix4::Invert()
tmp[9] = src[2] * src[4];
tmp[10] = src[0] * src[5];
tmp[11] = src[1] * src[4];
-
dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15];
dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15];
dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15];
@@ -190,17 +181,14 @@ void Matrix4::Invert()
dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9];
dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9];
dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8];
-
// Calculate determinant
det = src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3] * dst[3];
-
// Inverse of matrix is divided by determinant
det = 1 / det;
for (int j = 0; j < 16; j++)
{
dst[j] *= det;
}
-
// Set it back
for (int i = 0; i < 4; i++)
{
@@ -214,26 +202,21 @@ void Matrix4::Invert()
Matrix4 Matrix4::CreateFromQuaternion(const class Quaternion& q)
{
float mat[4][4];
-
mat[0][0] = 1.0f - 2.0f * q.y * q.y - 2.0f * q.z * q.z;
mat[0][1] = 2.0f * q.x * q.y + 2.0f * q.w * q.z;
mat[0][2] = 2.0f * q.x * q.z - 2.0f * q.w * q.y;
mat[0][3] = 0.0f;
-
mat[1][0] = 2.0f * q.x * q.y - 2.0f * q.w * q.z;
mat[1][1] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.z * q.z;
mat[1][2] = 2.0f * q.y * q.z + 2.0f * q.w * q.x;
mat[1][3] = 0.0f;
-
mat[2][0] = 2.0f * q.x * q.z + 2.0f * q.w * q.y;
mat[2][1] = 2.0f * q.y * q.z - 2.0f * q.w * q.x;
mat[2][2] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.y * q.y;
mat[2][3] = 0.0f;
-
mat[3][0] = 0.0f;
mat[3][1] = 0.0f;
mat[3][2] = 0.0f;
mat[3][3] = 1.0f;
-
return Matrix4(mat);
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Math.h b/Chapter05/Math.h
index 752963f1..281e0f37 100644
--- a/Chapter05/Math.h
+++ b/Chapter05/Math.h
@@ -24,12 +24,10 @@ namespace Math
{
return degrees * Pi / 180.0f;
}
-
inline float ToDegrees(float radians)
{
return radians * 180.0f / Pi;
}
-
inline bool NearZero(float val, float epsilon = 0.001f)
{
if (fabs(val) <= epsilon)
@@ -41,70 +39,57 @@ namespace Math
return false;
}
}
-
template
T Max(const T& a, const T& b)
{
return (a < b ? b : a);
}
-
template
T Min(const T& a, const T& b)
{
return (a < b ? a : b);
}
-
template
T Clamp(const T& value, const T& lower, const T& upper)
{
return Min(upper, Max(lower, value));
}
-
inline float Abs(float value)
{
return fabs(value);
}
-
inline float Cos(float angle)
{
return cosf(angle);
}
-
inline float Sin(float angle)
{
return sinf(angle);
}
-
inline float Tan(float angle)
{
return tanf(angle);
}
-
inline float Acos(float value)
{
return acosf(value);
}
-
inline float Atan2(float y, float x)
{
return atan2f(y, x);
}
-
inline float Cot(float angle)
{
return 1.0f / Tan(angle);
}
-
inline float Lerp(float a, float b, float f)
{
return a + f * (b - a);
}
-
inline float Sqrt(float value)
{
return sqrtf(value);
}
-
inline float Fmod(float numer, float denom)
{
return fmod(numer, denom);
@@ -118,54 +103,41 @@ class Vector2
float x;
float y;
- Vector2()
- :x(0.0f)
- ,y(0.0f)
+ Vector2(): x(0.0f), y(0.0f)
{}
-
- explicit Vector2(float inX, float inY)
- :x(inX)
- ,y(inY)
+ explicit Vector2(float inX, float inY): x(inX), y(inY)
{}
-
// Set both components in one line
void Set(float inX, float inY)
{
x = inX;
y = inY;
}
-
// Vector addition (a + b)
friend Vector2 operator+(const Vector2& a, const Vector2& b)
{
return Vector2(a.x + b.x, a.y + b.y);
}
-
// Vector subtraction (a - b)
friend Vector2 operator-(const Vector2& a, const Vector2& b)
{
return Vector2(a.x - b.x, a.y - b.y);
}
-
// Component-wise multiplication
- // (a.x * b.x, ...)
friend Vector2 operator*(const Vector2& a, const Vector2& b)
{
return Vector2(a.x * b.x, a.y * b.y);
}
-
// Scalar multiplication
friend Vector2 operator*(const Vector2& vec, float scalar)
{
return Vector2(vec.x * scalar, vec.y * scalar);
}
-
// Scalar multiplication
friend Vector2 operator*(float scalar, const Vector2& vec)
{
return Vector2(vec.x * scalar, vec.y * scalar);
}
-
// Scalar *=
Vector2& operator*=(float scalar)
{
@@ -173,7 +145,6 @@ class Vector2
y *= scalar;
return *this;
}
-
// Vector +=
Vector2& operator+=(const Vector2& right)
{
@@ -181,7 +152,6 @@ class Vector2
y += right.y;
return *this;
}
-
// Vector -=
Vector2& operator-=(const Vector2& right)
{
@@ -189,19 +159,16 @@ class Vector2
y -= right.y;
return *this;
}
-
// Length squared of vector
float LengthSq() const
{
return (x*x + y*y);
}
-
// Length of vector
float Length() const
{
return (Math::Sqrt(LengthSq()));
}
-
// Normalize this vector
void Normalize()
{
@@ -209,7 +176,6 @@ class Vector2
x /= length;
y /= length;
}
-
// Normalize the provided vector
static Vector2 Normalize(const Vector2& vec)
{
@@ -217,25 +183,21 @@ class Vector2
temp.Normalize();
return temp;
}
-
// Dot product between two vectors (a dot b)
static float Dot(const Vector2& a, const Vector2& b)
{
return (a.x * b.x + a.y * b.y);
}
-
// Lerp from A to B by f
static Vector2 Lerp(const Vector2& a, const Vector2& b, float f)
{
return Vector2(a + f * (b - a));
}
-
// Reflect V about (normalized) N
static Vector2 Reflect(const Vector2& v, const Vector2& n)
{
return v - 2.0f * Vector2::Dot(v, n) * n;
}
-
// Transform vector by matrix
static Vector2 Transform(const Vector2& vec, const class Matrix3& mat, float w = 1.0f);
@@ -254,24 +216,15 @@ class Vector3
float y;
float z;
- Vector3()
- :x(0.0f)
- ,y(0.0f)
- ,z(0.0f)
+ Vector3(): x(0.0f), y(0.0f), z(0.0f)
{}
-
- explicit Vector3(float inX, float inY, float inZ)
- :x(inX)
- ,y(inY)
- ,z(inZ)
+ explicit Vector3(float inX, float inY, float inZ): x(inX), y(inY), z(inZ)
{}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&x);
}
-
// Set all three components in one line
void Set(float inX, float inY, float inZ)
{
@@ -279,37 +232,31 @@ class Vector3
y = inY;
z = inZ;
}
-
// Vector addition (a + b)
friend Vector3 operator+(const Vector3& a, const Vector3& b)
{
return Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
}
-
// Vector subtraction (a - b)
friend Vector3 operator-(const Vector3& a, const Vector3& b)
{
return Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
}
-
// Component-wise multiplication
friend Vector3 operator*(const Vector3& left, const Vector3& right)
{
return Vector3(left.x * right.x, left.y * right.y, left.z * right.z);
}
-
// Scalar multiplication
friend Vector3 operator*(const Vector3& vec, float scalar)
{
return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
}
-
// Scalar multiplication
friend Vector3 operator*(float scalar, const Vector3& vec)
{
return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
}
-
// Scalar *=
Vector3& operator*=(float scalar)
{
@@ -318,7 +265,6 @@ class Vector3
z *= scalar;
return *this;
}
-
// Vector +=
Vector3& operator+=(const Vector3& right)
{
@@ -327,7 +273,6 @@ class Vector3
z += right.z;
return *this;
}
-
// Vector -=
Vector3& operator-=(const Vector3& right)
{
@@ -336,19 +281,26 @@ class Vector3
z -= right.z;
return *this;
}
-
+ // Vector ==
+ bool operator==(const Vector3& right)
+ {
+ return ((x == right.x) && (y == right.y) && (z == right.z));
+ }
+ // Vector !=
+ bool operator!=(const Vector3& right)
+ {
+ return !((x == right.x) && (y == right.y) && (z == right.z));
+ }
// Length squared of vector
float LengthSq() const
{
return (x*x + y*y + z*z);
}
-
// Length of vector
float Length() const
{
return (Math::Sqrt(LengthSq()));
}
-
// Normalize this vector
void Normalize()
{
@@ -357,7 +309,6 @@ class Vector3
y /= length;
z /= length;
}
-
// Normalize the provided vector
static Vector3 Normalize(const Vector3& vec)
{
@@ -365,13 +316,11 @@ class Vector3
temp.Normalize();
return temp;
}
-
// Dot product between two vectors (a dot b)
static float Dot(const Vector3& a, const Vector3& b)
{
return (a.x * b.x + a.y * b.y + a.z * b.z);
}
-
// Cross product between two vectors (a cross b)
static Vector3 Cross(const Vector3& a, const Vector3& b)
{
@@ -381,23 +330,19 @@ class Vector3
temp.z = a.x * b.y - a.y * b.x;
return temp;
}
-
// Lerp from A to B by f
static Vector3 Lerp(const Vector3& a, const Vector3& b, float f)
{
return Vector3(a + f * (b - a));
}
-
// Reflect V about (normalized) N
static Vector3 Reflect(const Vector3& v, const Vector3& n)
{
return v - 2.0f * Vector3::Dot(v, n) * n;
}
-
static Vector3 Transform(const Vector3& vec, const class Matrix4& mat, float w = 1.0f);
// This will transform the vector and renormalize the w component
static Vector3 TransformWithPerspDiv(const Vector3& vec, const class Matrix4& mat, float w = 1.0f);
-
// Transform a Vector3 by a quaternion
static Vector3 Transform(const Vector3& v, const class Quaternion& q);
@@ -422,18 +367,15 @@ class Matrix3
{
*this = Matrix3::Identity;
}
-
explicit Matrix3(float inMat[3][3])
{
memcpy(mat, inMat, 9 * sizeof(float));
}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&mat[0][0]);
}
-
// Matrix multiplication
friend Matrix3 operator*(const Matrix3& left, const Matrix3& right)
{
@@ -443,49 +385,40 @@ class Matrix3
left.mat[0][0] * right.mat[0][0] +
left.mat[0][1] * right.mat[1][0] +
left.mat[0][2] * right.mat[2][0];
-
retVal.mat[0][1] =
left.mat[0][0] * right.mat[0][1] +
left.mat[0][1] * right.mat[1][1] +
left.mat[0][2] * right.mat[2][1];
-
retVal.mat[0][2] =
left.mat[0][0] * right.mat[0][2] +
left.mat[0][1] * right.mat[1][2] +
left.mat[0][2] * right.mat[2][2];
-
// row 1
retVal.mat[1][0] =
left.mat[1][0] * right.mat[0][0] +
left.mat[1][1] * right.mat[1][0] +
left.mat[1][2] * right.mat[2][0];
-
retVal.mat[1][1] =
left.mat[1][0] * right.mat[0][1] +
left.mat[1][1] * right.mat[1][1] +
left.mat[1][2] * right.mat[2][1];
-
retVal.mat[1][2] =
left.mat[1][0] * right.mat[0][2] +
left.mat[1][1] * right.mat[1][2] +
left.mat[1][2] * right.mat[2][2];
-
// row 2
retVal.mat[2][0] =
left.mat[2][0] * right.mat[0][0] +
left.mat[2][1] * right.mat[1][0] +
left.mat[2][2] * right.mat[2][0];
-
retVal.mat[2][1] =
left.mat[2][0] * right.mat[0][1] +
left.mat[2][1] * right.mat[1][1] +
left.mat[2][2] * right.mat[2][1];
-
retVal.mat[2][2] =
left.mat[2][0] * right.mat[0][2] +
left.mat[2][1] * right.mat[1][2] +
left.mat[2][2] * right.mat[2][2];
-
return retVal;
}
@@ -556,18 +489,15 @@ class Matrix4
{
*this = Matrix4::Identity;
}
-
explicit Matrix4(float inMat[4][4])
{
memcpy(mat, inMat, 16 * sizeof(float));
}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&mat[0][0]);
}
-
// Matrix multiplication (a * b)
friend Matrix4 operator*(const Matrix4& a, const Matrix4& b)
{
@@ -578,136 +508,113 @@ class Matrix4
a.mat[0][1] * b.mat[1][0] +
a.mat[0][2] * b.mat[2][0] +
a.mat[0][3] * b.mat[3][0];
-
retVal.mat[0][1] =
a.mat[0][0] * b.mat[0][1] +
a.mat[0][1] * b.mat[1][1] +
a.mat[0][2] * b.mat[2][1] +
a.mat[0][3] * b.mat[3][1];
-
retVal.mat[0][2] =
a.mat[0][0] * b.mat[0][2] +
a.mat[0][1] * b.mat[1][2] +
a.mat[0][2] * b.mat[2][2] +
a.mat[0][3] * b.mat[3][2];
-
retVal.mat[0][3] =
a.mat[0][0] * b.mat[0][3] +
a.mat[0][1] * b.mat[1][3] +
a.mat[0][2] * b.mat[2][3] +
a.mat[0][3] * b.mat[3][3];
-
// row 1
retVal.mat[1][0] =
a.mat[1][0] * b.mat[0][0] +
a.mat[1][1] * b.mat[1][0] +
a.mat[1][2] * b.mat[2][0] +
a.mat[1][3] * b.mat[3][0];
-
retVal.mat[1][1] =
a.mat[1][0] * b.mat[0][1] +
a.mat[1][1] * b.mat[1][1] +
a.mat[1][2] * b.mat[2][1] +
a.mat[1][3] * b.mat[3][1];
-
retVal.mat[1][2] =
a.mat[1][0] * b.mat[0][2] +
a.mat[1][1] * b.mat[1][2] +
a.mat[1][2] * b.mat[2][2] +
a.mat[1][3] * b.mat[3][2];
-
retVal.mat[1][3] =
a.mat[1][0] * b.mat[0][3] +
a.mat[1][1] * b.mat[1][3] +
a.mat[1][2] * b.mat[2][3] +
a.mat[1][3] * b.mat[3][3];
-
// row 2
retVal.mat[2][0] =
a.mat[2][0] * b.mat[0][0] +
a.mat[2][1] * b.mat[1][0] +
a.mat[2][2] * b.mat[2][0] +
a.mat[2][3] * b.mat[3][0];
-
retVal.mat[2][1] =
a.mat[2][0] * b.mat[0][1] +
a.mat[2][1] * b.mat[1][1] +
a.mat[2][2] * b.mat[2][1] +
a.mat[2][3] * b.mat[3][1];
-
retVal.mat[2][2] =
a.mat[2][0] * b.mat[0][2] +
a.mat[2][1] * b.mat[1][2] +
a.mat[2][2] * b.mat[2][2] +
a.mat[2][3] * b.mat[3][2];
-
retVal.mat[2][3] =
a.mat[2][0] * b.mat[0][3] +
a.mat[2][1] * b.mat[1][3] +
a.mat[2][2] * b.mat[2][3] +
a.mat[2][3] * b.mat[3][3];
-
// row 3
retVal.mat[3][0] =
a.mat[3][0] * b.mat[0][0] +
a.mat[3][1] * b.mat[1][0] +
a.mat[3][2] * b.mat[2][0] +
a.mat[3][3] * b.mat[3][0];
-
retVal.mat[3][1] =
a.mat[3][0] * b.mat[0][1] +
a.mat[3][1] * b.mat[1][1] +
a.mat[3][2] * b.mat[2][1] +
a.mat[3][3] * b.mat[3][1];
-
retVal.mat[3][2] =
a.mat[3][0] * b.mat[0][2] +
a.mat[3][1] * b.mat[1][2] +
a.mat[3][2] * b.mat[2][2] +
a.mat[3][3] * b.mat[3][2];
-
retVal.mat[3][3] =
a.mat[3][0] * b.mat[0][3] +
a.mat[3][1] * b.mat[1][3] +
a.mat[3][2] * b.mat[2][3] +
a.mat[3][3] * b.mat[3][3];
-
return retVal;
}
-
Matrix4& operator*=(const Matrix4& right)
{
*this = *this * right;
return *this;
}
-
// Invert the matrix - super slow
void Invert();
-
// Get the translation component of the matrix
Vector3 GetTranslation() const
{
return Vector3(mat[3][0], mat[3][1], mat[3][2]);
}
-
// Get the X axis of the matrix (forward)
Vector3 GetXAxis() const
{
return Vector3::Normalize(Vector3(mat[0][0], mat[0][1], mat[0][2]));
}
-
// Get the Y axis of the matrix (left)
Vector3 GetYAxis() const
{
return Vector3::Normalize(Vector3(mat[1][0], mat[1][1], mat[1][2]));
}
-
// Get the Z axis of the matrix (up)
Vector3 GetZAxis() const
{
return Vector3::Normalize(Vector3(mat[2][0], mat[2][1], mat[2][2]));
}
-
// Extract the scale component from the matrix
Vector3 GetScale() const
{
@@ -717,7 +624,6 @@ class Matrix4
retVal.z = Vector3(mat[2][0], mat[2][1], mat[2][2]).Length();
return retVal;
}
-
// Create a scale matrix with x, y, and z scales
static Matrix4 CreateScale(float xScale, float yScale, float zScale)
{
@@ -730,18 +636,15 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateScale(const Vector3& scaleVector)
{
return CreateScale(scaleVector.x, scaleVector.y, scaleVector.z);
}
-
// Create a scale matrix with a uniform factor
static Matrix4 CreateScale(float scale)
{
return CreateScale(scale, scale, scale);
}
-
// Rotation about x-axis
static Matrix4 CreateRotationX(float theta)
{
@@ -754,7 +657,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Rotation about y-axis
static Matrix4 CreateRotationY(float theta)
{
@@ -767,7 +669,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Rotation about z-axis
static Matrix4 CreateRotationZ(float theta)
{
@@ -780,10 +681,8 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Create a rotation matrix from a quaternion
static Matrix4 CreateFromQuaternion(const class Quaternion& q);
-
static Matrix4 CreateTranslation(const Vector3& trans)
{
float temp[4][4] =
@@ -795,7 +694,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
{
Vector3 zaxis = Vector3::Normalize(target - eye);
@@ -805,7 +703,6 @@ class Matrix4
trans.x = -Vector3::Dot(xaxis, eye);
trans.y = -Vector3::Dot(yaxis, eye);
trans.z = -Vector3::Dot(zaxis, eye);
-
float temp[4][4] =
{
{ xaxis.x, yaxis.x, zaxis.x, 0.0f },
@@ -815,7 +712,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateOrtho(float width, float height, float near, float far)
{
float temp[4][4] =
@@ -827,7 +723,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreatePerspectiveFOV(float fovY, float width, float height, float near, float far)
{
float yScale = Math::Cot(fovY / 2.0f);
@@ -841,7 +736,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Create "Simple" View-Projection Matrix from Chapter 6
static Matrix4 CreateSimpleViewProj(float width, float height)
{
@@ -871,17 +765,13 @@ class Quaternion
{
*this = Quaternion::Identity;
}
-
- // This directly sets the quaternion components --
- // don't use for axis/angle
+ // This directly sets the quaternion components -- don't use for axis/angle
explicit Quaternion(float inX, float inY, float inZ, float inW)
{
Set(inX, inY, inZ, inW);
}
-
- // Construct the quaternion from an axis and angle
- // It is assumed that axis is already normalized,
- // and the angle is in radians
+ /* Construct the quaternion from an axis and angle
+ NOTE: It is assumed that axis is already normalized, and the angle is in radians*/
explicit Quaternion(const Vector3& axis, float angle)
{
float scalar = Math::Sin(angle / 2.0f);
@@ -890,7 +780,6 @@ class Quaternion
z = axis.z * scalar;
w = Math::Cos(angle / 2.0f);
}
-
// Directly set the internal components
void Set(float inX, float inY, float inZ, float inW)
{
@@ -899,24 +788,20 @@ class Quaternion
z = inZ;
w = inW;
}
-
void Conjugate()
{
x *= -1.0f;
y *= -1.0f;
z *= -1.0f;
}
-
float LengthSq() const
{
return (x*x + y*y + z*z + w*w);
}
-
float Length() const
{
return Math::Sqrt(LengthSq());
}
-
void Normalize()
{
float length = Length();
@@ -925,7 +810,6 @@ class Quaternion
z /= length;
w /= length;
}
-
// Normalize the provided quaternion
static Quaternion Normalize(const Quaternion& q)
{
@@ -933,7 +817,6 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
// Linear interpolation
static Quaternion Lerp(const Quaternion& a, const Quaternion& b, float f)
{
@@ -945,25 +828,20 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
static float Dot(const Quaternion& a, const Quaternion& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}
-
// Spherical Linear Interpolation
static Quaternion Slerp(const Quaternion& a, const Quaternion& b, float f)
{
float rawCosm = Quaternion::Dot(a, b);
-
float cosom = -rawCosm;
if (rawCosm >= 0.0f)
{
cosom = rawCosm;
}
-
float scale0, scale1;
-
if (cosom < 0.9999f)
{
const float omega = Math::Acos(cosom);
@@ -973,17 +851,14 @@ class Quaternion
}
else
{
- // Use linear interpolation if the quaternions
- // are collinear
+ // Use linear interpolation if the quaternions are collinear
scale0 = 1.0f - f;
scale1 = f;
}
-
if (rawCosm < 0.0f)
{
scale1 = -scale1;
}
-
Quaternion retVal;
retVal.x = scale0 * a.x + scale1 * b.x;
retVal.y = scale0 * a.y + scale1 * b.y;
@@ -992,13 +867,11 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
// Concatenate
// Rotate by q FOLLOWED BY p
static Quaternion Concatenate(const Quaternion& q, const Quaternion& p)
{
Quaternion retVal;
-
// Vector component is:
// ps * qv + qs * pv + pv x qv
Vector3 qv(q.x, q.y, q.z);
@@ -1007,11 +880,9 @@ class Quaternion
retVal.x = newVec.x;
retVal.y = newVec.y;
retVal.z = newVec.z;
-
// Scalar component is:
// ps * qs - pv . qv
retVal.w = p.w * q.w - Vector3::Dot(pv, qv);
-
return retVal;
}
@@ -1030,4 +901,4 @@ namespace Color
static const Vector3 LightBlue(0.68f, 0.85f, 0.9f);
static const Vector3 LightPink(1.0f, 0.71f, 0.76f);
static const Vector3 LightGreen(0.56f, 0.93f, 0.56f);
-}
+}
\ No newline at end of file
diff --git a/Chapter05/MoveComponent.cpp b/Chapter05/MoveComponent.cpp
index c1a5d5b2..07cc854b 100644
--- a/Chapter05/MoveComponent.cpp
+++ b/Chapter05/MoveComponent.cpp
@@ -9,33 +9,28 @@
#include "MoveComponent.h"
#include "Actor.h"
-MoveComponent::MoveComponent(class Actor* owner, int updateOrder)
-:Component(owner, updateOrder)
-,mAngularSpeed(0.0f)
-,mForwardSpeed(0.0f)
+MoveComponent::MoveComponent(class Actor* owner, int updateOrder): Component(owner, updateOrder), mAngularSpeed(0.0f), mForwardSpeed(0.0f)
{
-
}
void MoveComponent::Update(float deltaTime)
{
if (!Math::NearZero(mAngularSpeed))
{
- float rot = mOwner->GetRotation();
+ float rot = pOwner->GetRotation();
rot += mAngularSpeed * deltaTime;
- mOwner->SetRotation(rot);
+ pOwner->SetRotation(rot);
}
-
if (!Math::NearZero(mForwardSpeed))
{
- Vector2 pos = mOwner->GetPosition();
- pos += mOwner->GetForward() * mForwardSpeed * deltaTime;
+ Vector2 pos = pOwner->GetPosition();
+ pos += pOwner->GetForward() * mForwardSpeed * deltaTime;
// Screen wrapping (for asteroids)
if (pos.x < -512.0f) { pos.x = 510.0f; }
else if (pos.x > 512.0f) { pos.x = -510.0f; }
if (pos.y < -384.0f) { pos.y = 382.0f; }
else if (pos.y > 384.0f) { pos.y = -382.0f; }
- mOwner->SetPosition(pos);
+ pOwner->SetPosition(pos);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter05/MoveComponent.h b/Chapter05/MoveComponent.h
index def7d389..c737e66b 100644
--- a/Chapter05/MoveComponent.h
+++ b/Chapter05/MoveComponent.h
@@ -9,13 +9,12 @@
#pragma once
#include "Component.h"
-class MoveComponent : public Component
+class MoveComponent: public Component
{
public:
// Lower update order to update first
MoveComponent(class Actor* owner, int updateOrder = 10);
void Update(float deltaTime) override;
-
float GetAngularSpeed() const { return mAngularSpeed; }
float GetForwardSpeed() const { return mForwardSpeed; }
void SetAngularSpeed(float speed) { mAngularSpeed = speed; }
@@ -23,4 +22,4 @@ class MoveComponent : public Component
private:
float mAngularSpeed;
float mForwardSpeed;
-};
+};
\ No newline at end of file
diff --git a/Chapter05/Random.cpp b/Chapter05/Random.cpp
index 05a3a32a..df2da134 100644
--- a/Chapter05/Random.cpp
+++ b/Chapter05/Random.cpp
@@ -48,4 +48,4 @@ Vector3 Random::GetVector(const Vector3& min, const Vector3& max)
return min + (max - min) * r;
}
-std::mt19937 Random::sGenerator;
+std::mt19937 Random::sGenerator;
\ No newline at end of file
diff --git a/Chapter05/Random.h b/Chapter05/Random.h
index 3ae92fe5..cd216013 100644
--- a/Chapter05/Random.h
+++ b/Chapter05/Random.h
@@ -14,23 +14,18 @@ class Random
{
public:
static void Init();
-
// Seed the generator with the specified int
// NOTE: You should generally not need to manually use this
static void Seed(unsigned int seed);
-
// Get a float between 0.0f and 1.0f
static float GetFloat();
-
// Get a float from the specified range
static float GetFloatRange(float min, float max);
-
// Get an int from the specified range
static int GetIntRange(int min, int max);
-
// Get a random vector given the min/max bounds
static Vector2 GetVector(const Vector2& min, const Vector2& max);
static Vector3 GetVector(const Vector3& min, const Vector3& max);
private:
static std::mt19937 sGenerator;
-};
+};
\ No newline at end of file
diff --git a/Chapter05/Shader.cpp b/Chapter05/Shader.cpp
index e32c07a2..ba8e5435 100644
--- a/Chapter05/Shader.cpp
+++ b/Chapter05/Shader.cpp
@@ -12,46 +12,28 @@
#include
#include
-Shader::Shader()
- : mShaderProgram(0)
- , mVertexShader(0)
- , mFragShader(0)
+Shader::Shader(): mShaderProgram(0), mVertexShader(0), mFragShader(0)
{
-
}
Shader::~Shader()
{
-
}
bool Shader::Load(const std::string& vertName, const std::string& fragName)
{
// Compile vertex and pixel shaders
- if (!CompileShader(vertName,
- GL_VERTEX_SHADER,
- mVertexShader) ||
- !CompileShader(fragName,
- GL_FRAGMENT_SHADER,
- mFragShader))
+ if (!CompileShader(vertName, GL_VERTEX_SHADER, mVertexShader) || !CompileShader(fragName, GL_FRAGMENT_SHADER, mFragShader))
{
return false;
}
-
- // Now create a shader program that
- // links together the vertex/frag shaders
+ // Now create a shader program that links together the vertex/frag shaders
mShaderProgram = glCreateProgram();
glAttachShader(mShaderProgram, mVertexShader);
glAttachShader(mShaderProgram, mFragShader);
glLinkProgram(mShaderProgram);
-
// Verify that the program linked successfully
- if (!IsValidProgram())
- {
- return false;
- }
-
- return true;
+ return IsValidProgram();
}
void Shader::Unload()
@@ -76,9 +58,7 @@ void Shader::SetMatrixUniform(const char* name, const Matrix4& matrix)
glUniformMatrix4fv(loc, 1, GL_TRUE, matrix.GetAsFloatPtr());
}
-bool Shader::CompileShader(const std::string& fileName,
- GLenum shaderType,
- GLuint& outShader)
+bool Shader::CompileShader(const std::string& fileName, GLenum shaderType, GLuint& outShader)
{
// Open file
std::ifstream shaderFile(fileName);
@@ -89,13 +69,11 @@ bool Shader::CompileShader(const std::string& fileName,
sstream << shaderFile.rdbuf();
std::string contents = sstream.str();
const char* contentsChar = contents.c_str();
-
// Create a shader of the specified type
outShader = glCreateShader(shaderType);
// Set the source characters and try to compile
glShaderSource(outShader, 1, &(contentsChar), nullptr);
glCompileShader(outShader);
-
if (!IsCompiled(outShader))
{
SDL_Log("Failed to compile shader %s", fileName.c_str());
@@ -107,7 +85,6 @@ bool Shader::CompileShader(const std::string& fileName,
SDL_Log("Shader file not found: %s", fileName.c_str());
return false;
}
-
return true;
}
@@ -116,7 +93,6 @@ bool Shader::IsCompiled(GLuint shader)
GLint status;
// Query the compile status
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
-
if (status != GL_TRUE)
{
char buffer[512];
@@ -125,13 +101,11 @@ bool Shader::IsCompiled(GLuint shader)
SDL_Log("GLSL Compile Failed:\n%s", buffer);
return false;
}
-
return true;
}
bool Shader::IsValidProgram()
{
-
GLint status;
// Query the link status
glGetProgramiv(mShaderProgram, GL_LINK_STATUS, &status);
@@ -143,6 +117,5 @@ bool Shader::IsValidProgram()
SDL_Log("GLSL Link Status:\n%s", buffer);
return false;
}
-
return true;
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Shader.h b/Chapter05/Shader.h
index 2b0161c0..445951d6 100644
--- a/Chapter05/Shader.h
+++ b/Chapter05/Shader.h
@@ -25,10 +25,7 @@ class Shader
void SetMatrixUniform(const char* name, const Matrix4& matrix);
private:
// Tries to compile the specified shader
- bool CompileShader(const std::string& fileName,
- GLenum shaderType,
- GLuint& outShader);
-
+ bool CompileShader(const std::string& fileName, GLenum shaderType, GLuint& outShader);
// Tests whether shader compiled successfully
bool IsCompiled(GLuint shader);
// Tests whether vertex/fragment programs link
@@ -38,4 +35,4 @@ class Shader
GLuint mVertexShader;
GLuint mFragShader;
GLuint mShaderProgram;
-};
+};
\ No newline at end of file
diff --git a/Chapter05/Shaders/Basic.frag b/Chapter05/Shaders/Basic.frag
index af9a33e5..ab3ab9b0 100644
--- a/Chapter05/Shaders/Basic.frag
+++ b/Chapter05/Shaders/Basic.frag
@@ -9,12 +9,11 @@
// Request GLSL 3.3
#version 330
-// This corresponds to the output color
-// to the color buffer
+// This corresponds to the output color to the color buffer
out vec4 outColor;
void main()
{
// RGBA of 100% blue, 100% opaque
outColor = vec4(0.0, 0.0, 1.0, 1.0);
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Shaders/Basic.vert b/Chapter05/Shaders/Basic.vert
index 345b3c05..4c62a33f 100644
--- a/Chapter05/Shaders/Basic.vert
+++ b/Chapter05/Shaders/Basic.vert
@@ -20,4 +20,4 @@ void main()
// coordinate.
// For now set the 4th coordinate to 1.0
gl_Position = vec4(inPosition, 1.0);
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Shaders/Sprite.frag b/Chapter05/Shaders/Sprite.frag
index f48caf3d..215f65f9 100644
--- a/Chapter05/Shaders/Sprite.frag
+++ b/Chapter05/Shaders/Sprite.frag
@@ -11,15 +11,18 @@
// Tex coord input from vertex shader
in vec2 fragTexCoord;
-
+// Vertex color
+in vec3 vertexColor;
// This corresponds to the output color to the color buffer
out vec4 outColor;
-
// This is used for the texture sampling
uniform sampler2D uTexture;
void main()
{
// Sample color from texture
- outColor = texture(uTexture, fragTexCoord);
-}
+ float x = (texture(uTexture, fragTexCoord).x * vertexColor.x)/2;
+ float y = (texture(uTexture, fragTexCoord).y * vertexColor.y)/2;
+ float z = (texture(uTexture, fragTexCoord).z * vertexColor.z)/2;
+ outColor = vec4(x, y, z, texture(uTexture, fragTexCoord).w);
+}
\ No newline at end of file
diff --git a/Chapter05/Shaders/Sprite.vert b/Chapter05/Shaders/Sprite.vert
index ea0f396f..0e9e1c3b 100644
--- a/Chapter05/Shaders/Sprite.vert
+++ b/Chapter05/Shaders/Sprite.vert
@@ -12,13 +12,14 @@
// Uniforms for world transform and view-proj
uniform mat4 uWorldTransform;
uniform mat4 uViewProj;
-
// Attribute 0 is position, 1 is tex coords.
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec2 inTexCoord;
-
+layout(location = 2) in vec3 inVertColor;
// Add texture coordinate as output
out vec2 fragTexCoord;
+// Add vertex color as output
+out vec3 vertexColor;
void main()
{
@@ -26,8 +27,9 @@ void main()
vec4 pos = vec4(inPosition, 1.0);
// Transform position to world space, then clip space
gl_Position = pos * uWorldTransform * uViewProj;
-
// Transform
// Pass along the texture coordinate to frag shader
fragTexCoord = inTexCoord;
-}
+ // Pass along the vertex color to frag shader
+ vertexColor = inVertColor;
+}
\ No newline at end of file
diff --git a/Chapter05/Shaders/Transform.vert b/Chapter05/Shaders/Transform.vert
index fc59d32e..7f38dd4f 100644
--- a/Chapter05/Shaders/Transform.vert
+++ b/Chapter05/Shaders/Transform.vert
@@ -12,7 +12,6 @@
// Uniforms for world transform and view-proj
uniform mat4 uWorldTransform;
uniform mat4 uViewProj;
-
// Vertex attributes
in vec3 inPosition;
@@ -20,4 +19,4 @@ void main()
{
vec4 pos = vec4(inPosition, 1.0);
gl_Position = pos * uWorldTransform * uViewProj;
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Ship.cpp b/Chapter05/Ship.cpp
index e5b236db..a3772380 100644
--- a/Chapter05/Ship.cpp
+++ b/Chapter05/Ship.cpp
@@ -12,14 +12,11 @@
#include "Game.h"
#include "Laser.h"
-Ship::Ship(Game* game)
- :Actor(game)
- ,mLaserCooldown(0.0f)
+Ship::Ship(Game* game): Actor(game), mLaserCooldown(0.0f)
{
// Create a sprite component
SpriteComponent* sc = new SpriteComponent(this, 150);
sc->SetTexture(game->GetTexture("Assets/Ship.png"));
-
// Create an input component and set keys/speed
InputComponent* ic = new InputComponent(this);
ic->SetForwardKey(SDL_SCANCODE_W);
@@ -43,8 +40,7 @@ void Ship::ActorInput(const uint8_t* keyState)
Laser* laser = new Laser(GetGame());
laser->SetPosition(GetPosition());
laser->SetRotation(GetRotation());
-
// Reset laser cooldown (half second)
mLaserCooldown = 0.5f;
}
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Ship.h b/Chapter05/Ship.h
index 808639ff..9ac4a6f2 100644
--- a/Chapter05/Ship.h
+++ b/Chapter05/Ship.h
@@ -8,11 +8,10 @@
#pragma once
#include "Actor.h"
-class Ship : public Actor
+class Ship: public Actor
{
public:
Ship(class Game* game);
-
void UpdateActor(float deltaTime) override;
void ActorInput(const uint8_t* keyState) override;
private:
diff --git a/Chapter05/SpriteComponent.cpp b/Chapter05/SpriteComponent.cpp
index d62b9840..57127170 100644
--- a/Chapter05/SpriteComponent.cpp
+++ b/Chapter05/SpriteComponent.cpp
@@ -12,40 +12,28 @@
#include "Actor.h"
#include "Game.h"
-SpriteComponent::SpriteComponent(Actor* owner, int drawOrder)
- :Component(owner)
- ,mTexture(nullptr)
- ,mDrawOrder(drawOrder)
- ,mTexWidth(0)
- ,mTexHeight(0)
+SpriteComponent::SpriteComponent(Actor* owner, int drawOrder): Component(owner), pTexture(nullptr), mDrawOrder(drawOrder), mTexWidth(0), mTexHeight(0)
{
- mOwner->GetGame()->AddSprite(this);
+ pOwner->GetGame()->AddSprite(this);
}
SpriteComponent::~SpriteComponent()
{
- mOwner->GetGame()->RemoveSprite(this);
+ pOwner->GetGame()->RemoveSprite(this);
}
void SpriteComponent::Draw(Shader* shader)
{
- if (mTexture)
+ if (pTexture)
{
// Scale the quad by the width/height of texture
- Matrix4 scaleMat = Matrix4::CreateScale(
- static_cast(mTexWidth),
- static_cast(mTexHeight),
- 1.0f);
-
- Matrix4 world = scaleMat * mOwner->GetWorldTransform();
-
- // Since all sprites use the same shader/vertices,
- // the game first sets them active before any sprite draws
-
+ Matrix4 scaleMat = Matrix4::CreateScale(static_cast(mTexWidth), static_cast(mTexHeight), 1.0f);
+ Matrix4 world = scaleMat * pOwner->GetWorldTransform();
+ // NOTE: Since all sprites use the same shader/vertices, the game first sets them active before any sprite draws
// Set world transform
shader->SetMatrixUniform("uWorldTransform", world);
// Set current texture
- mTexture->SetActive();
+ pTexture->SetActive();
// Draw quad
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
}
@@ -53,8 +41,8 @@ void SpriteComponent::Draw(Shader* shader)
void SpriteComponent::SetTexture(Texture* texture)
{
- mTexture = texture;
+ pTexture = texture;
// Set width/height
mTexWidth = texture->GetWidth();
mTexHeight = texture->GetHeight();
-}
+}
\ No newline at end of file
diff --git a/Chapter05/SpriteComponent.h b/Chapter05/SpriteComponent.h
index 6c5642f2..581cb883 100644
--- a/Chapter05/SpriteComponent.h
+++ b/Chapter05/SpriteComponent.h
@@ -9,22 +9,20 @@
#pragma once
#include "Component.h"
#include "SDL/SDL.h"
-class SpriteComponent : public Component
+class SpriteComponent: public Component
{
public:
// (Lower draw order corresponds with further back)
SpriteComponent(class Actor* owner, int drawOrder = 100);
~SpriteComponent();
-
virtual void Draw(class Shader* shader);
virtual void SetTexture(class Texture* texture);
-
int GetDrawOrder() const { return mDrawOrder; }
int GetTexHeight() const { return mTexHeight; }
int GetTexWidth() const { return mTexWidth; }
protected:
- class Texture* mTexture;
+ class Texture* pTexture;
int mDrawOrder;
int mTexWidth;
int mTexHeight;
-};
+};
\ No newline at end of file
diff --git a/Chapter05/Texture.cpp b/Chapter05/Texture.cpp
index 7d0dbd3e..a25c7d52 100644
--- a/Chapter05/Texture.cpp
+++ b/Chapter05/Texture.cpp
@@ -11,50 +11,35 @@
#include
#include
-Texture::Texture()
-:mTextureID(0)
-,mWidth(0)
-,mHeight(0)
+Texture::Texture(): mTextureID(0), mWidth(0), mHeight(0)
{
-
}
Texture::~Texture()
{
-
}
bool Texture::Load(const std::string& fileName)
{
int channels = 0;
-
- unsigned char* image = SOIL_load_image(fileName.c_str(),
- &mWidth, &mHeight, &channels, SOIL_LOAD_AUTO);
-
+ unsigned char* image = SOIL_load_image(fileName.c_str(), &mWidth, &mHeight, &channels, SOIL_LOAD_AUTO);
if (image == nullptr)
{
SDL_Log("SOIL failed to load image %s: %s", fileName.c_str(), SOIL_last_result());
return false;
}
-
int format = GL_RGB;
if (channels == 4)
{
format = GL_RGBA;
}
-
glGenTextures(1, &mTextureID);
glBindTexture(GL_TEXTURE_2D, mTextureID);
-
- glTexImage2D(GL_TEXTURE_2D, 0, format, mWidth, mHeight, 0, format,
- GL_UNSIGNED_BYTE, image);
-
+ glTexImage2D(GL_TEXTURE_2D, 0, format, mWidth, mHeight, 0, format, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
-
// Enable bilinear filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
return true;
}
@@ -66,4 +51,4 @@ void Texture::Unload()
void Texture::SetActive()
{
glBindTexture(GL_TEXTURE_2D, mTextureID);
-}
+}
\ No newline at end of file
diff --git a/Chapter05/Texture.h b/Chapter05/Texture.h
index ed12b0dc..b745ffac 100644
--- a/Chapter05/Texture.h
+++ b/Chapter05/Texture.h
@@ -13,12 +13,9 @@ class Texture
public:
Texture();
~Texture();
-
bool Load(const std::string& fileName);
void Unload();
-
void SetActive();
-
int GetWidth() const { return mWidth; }
int GetHeight() const { return mHeight; }
private:
@@ -27,4 +24,4 @@ class Texture
// Width/height of the texture
int mWidth;
int mHeight;
-};
+};
\ No newline at end of file
diff --git a/Chapter05/VertexArray.cpp b/Chapter05/VertexArray.cpp
index c7bff446..3b596c1e 100644
--- a/Chapter05/VertexArray.cpp
+++ b/Chapter05/VertexArray.cpp
@@ -9,33 +9,30 @@
#include "VertexArray.h"
#include
-VertexArray::VertexArray(const float* verts, unsigned int numVerts,
- const unsigned int* indices, unsigned int numIndices)
- :mNumVerts(numVerts)
- ,mNumIndices(numIndices)
+VertexArray::VertexArray(const float* verts, const int size, unsigned int numVerts, const unsigned int* indices, unsigned int numIndices): mNumVerts(numVerts), mNumIndices(numIndices)
{
// Create vertex array
glGenVertexArrays(1, &mVertexArray);
glBindVertexArray(mVertexArray);
-
// Create vertex buffer
glGenBuffers(1, &mVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
- glBufferData(GL_ARRAY_BUFFER, numVerts * 5 * sizeof(float), verts, GL_STATIC_DRAW);
-
+ glBufferData(GL_ARRAY_BUFFER, numVerts * size * sizeof(float), verts, GL_STATIC_DRAW);
// Create index buffer
glGenBuffers(1, &mIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(unsigned int), indices, GL_STATIC_DRAW);
-
- // Specify the vertex attributes
- // (For now, assume one vertex format)
- // Position is 3 floats starting at offset 0
+ /* Specify the vertex attributes (For now, assume one vertex format)
+ NOTE: Position is 3 floats starting at offset 0*/
glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * size, 0);
glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5,
- reinterpret_cast(sizeof(float) * 3));
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * size, reinterpret_cast(sizeof(float) * 3));
+ // Tell OpenGl we want to create a new Attribute ID=2
+ glEnableVertexAttribArray(2);
+ // Tell OpenGL we want to create a Vecter3 of floats
+ // NOTE: ID, vector size, type, IDK, total size, starting index
+ glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(float) * size, reinterpret_cast(sizeof(float) * 5));
}
VertexArray::~VertexArray()
@@ -48,4 +45,4 @@ VertexArray::~VertexArray()
void VertexArray::SetActive()
{
glBindVertexArray(mVertexArray);
-}
+}
\ No newline at end of file
diff --git a/Chapter05/VertexArray.h b/Chapter05/VertexArray.h
index 9f2c3e9b..6a5e59c9 100644
--- a/Chapter05/VertexArray.h
+++ b/Chapter05/VertexArray.h
@@ -10,13 +10,10 @@
class VertexArray
{
public:
- VertexArray(const float* verts, unsigned int numVerts,
- const unsigned int* indices, unsigned int numIndices);
+ VertexArray(const float* verts, const int size, unsigned int numVerts, const unsigned int* indices, unsigned int numIndices);
~VertexArray();
-
// Activate this vertex array (so we can draw it)
void SetActive();
-
unsigned int GetNumIndices() const { return mNumIndices; }
unsigned int GetNumVerts() const { return mNumVerts; }
private:
diff --git a/Chapter06/Actor.cpp b/Chapter06/Actor.cpp
index b3715cca..321fc7ca 100644
--- a/Chapter06/Actor.cpp
+++ b/Chapter06/Actor.cpp
@@ -11,20 +11,14 @@
#include "Component.h"
#include
-Actor::Actor(Game* game)
- :mState(EActive)
- ,mPosition(Vector3::Zero)
- ,mRotation(Quaternion::Identity)
- ,mScale(1.0f)
- ,mGame(game)
- ,mRecomputeWorldTransform(true)
+Actor::Actor(Game* game): mState(EActive), mPosition(Vector3::Zero), mRotation(Quaternion::Identity), mScale(1.0f), pGame(game), mRecomputeWorldTransform(true)
{
- mGame->AddActor(this);
+ pGame->AddActor(this);
}
Actor::~Actor()
{
- mGame->RemoveActor(this);
+ pGame->RemoveActor(this);
// Need to delete components
// Because ~Component calls RemoveComponent, need a different style loop
while (!mComponents.empty())
@@ -38,17 +32,15 @@ void Actor::Update(float deltaTime)
if (mState == EActive)
{
ComputeWorldTransform();
-
UpdateComponents(deltaTime);
UpdateActor(deltaTime);
-
ComputeWorldTransform();
}
}
void Actor::UpdateComponents(float deltaTime)
{
- for (auto comp : mComponents)
+ for (auto comp: mComponents)
{
comp->Update(deltaTime);
}
@@ -63,11 +55,10 @@ void Actor::ProcessInput(const uint8_t* keyState)
if (mState == EActive)
{
// First process input for components
- for (auto comp : mComponents)
+ for (auto comp: mComponents)
{
comp->ProcessInput(keyState);
}
-
ActorInput(keyState);
}
}
@@ -85,7 +76,6 @@ void Actor::ComputeWorldTransform()
mWorldTransform = Matrix4::CreateScale(mScale);
mWorldTransform *= Matrix4::CreateFromQuaternion(mRotation);
mWorldTransform *= Matrix4::CreateTranslation(mPosition);
-
// Inform components world transform updated
for (auto comp : mComponents)
{
@@ -100,16 +90,13 @@ void Actor::AddComponent(Component* component)
// (The first element with a order higher than me)
int myOrder = component->GetUpdateOrder();
auto iter = mComponents.begin();
- for (;
- iter != mComponents.end();
- ++iter)
+ for (; iter != mComponents.end(); ++iter)
{
if (myOrder < (*iter)->GetUpdateOrder())
{
break;
}
}
-
// Inserts element before position of iterator
mComponents.insert(iter, component);
}
@@ -121,4 +108,4 @@ void Actor::RemoveComponent(Component* component)
{
mComponents.erase(iter);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Actor.h b/Chapter06/Actor.h
index 05d6b1b6..59421c32 100644
--- a/Chapter06/Actor.h
+++ b/Chapter06/Actor.h
@@ -20,22 +20,18 @@ class Actor
EPaused,
EDead
};
-
Actor(class Game* game);
virtual ~Actor();
-
// Update function called from Game (not overridable)
void Update(float deltaTime);
// Updates all the components attached to the actor (not overridable)
void UpdateComponents(float deltaTime);
// Any actor-specific update code (overridable)
virtual void UpdateActor(float deltaTime);
-
// ProcessInput function called from Game (not overridable)
void ProcessInput(const uint8_t* keyState);
// Any actor-specific input code (overridable)
virtual void ActorInput(const uint8_t* keyState);
-
// Getters/setters
const Vector3& GetPosition() const { return mPosition; }
void SetPosition(const Vector3& pos) { mPosition = pos; mRecomputeWorldTransform = true; }
@@ -43,32 +39,24 @@ class Actor
void SetScale(float scale) { mScale = scale; mRecomputeWorldTransform = true; }
const Quaternion& GetRotation() const { return mRotation; }
void SetRotation(const Quaternion& rotation) { mRotation = rotation; mRecomputeWorldTransform = true; }
-
void ComputeWorldTransform();
const Matrix4& GetWorldTransform() const { return mWorldTransform; }
-
Vector3 GetForward() const { return Vector3::Transform(Vector3::UnitX, mRotation); }
-
State GetState() const { return mState; }
void SetState(State state) { mState = state; }
-
- class Game* GetGame() { return mGame; }
-
-
+ class Game* GetGame() { return pGame; }
// Add/remove components
void AddComponent(class Component* component);
void RemoveComponent(class Component* component);
private:
// Actor's state
State mState;
-
// Transform
Matrix4 mWorldTransform;
Vector3 mPosition;
Quaternion mRotation;
float mScale;
bool mRecomputeWorldTransform;
-
std::vector mComponents;
- class Game* mGame;
-};
+ class Game* pGame;
+};
\ No newline at end of file
diff --git a/Chapter06/Assets/Cube.gpmesh b/Chapter06/Assets/Cube.gpmesh
index 408d9061..99a347da 100644
--- a/Chapter06/Assets/Cube.gpmesh
+++ b/Chapter06/Assets/Cube.gpmesh
@@ -1,7 +1,7 @@
{
"version":1,
"vertexformat":"PosNormTex",
- "shader":"BasicMesh",
+ "shader":"Phong",
"textures":[
"Assets/Cube.png"
],
diff --git a/Chapter06/Assets/Sphere.gpmesh b/Chapter06/Assets/Sphere.gpmesh
index 82ed952c..51b46a4c 100644
--- a/Chapter06/Assets/Sphere.gpmesh
+++ b/Chapter06/Assets/Sphere.gpmesh
@@ -1,7 +1,7 @@
{
"version":1,
"vertexformat":"PosNormTex",
- "shader":"BasicMesh",
+ "shader":"Phong",
"textures":[
"Assets/Sphere.png"
],
diff --git a/Chapter06/CameraActor.cpp b/Chapter06/CameraActor.cpp
index 5338b1bf..af63bf7f 100644
--- a/Chapter06/CameraActor.cpp
+++ b/Chapter06/CameraActor.cpp
@@ -12,21 +12,18 @@
#include "Renderer.h"
#include "Game.h"
-CameraActor::CameraActor(Game* game)
- :Actor(game)
+CameraActor::CameraActor(Game* game): Actor(game)
{
- mMoveComp = new MoveComponent(this);
+ pMoveComp = new MoveComponent(this);
}
void CameraActor::UpdateActor(float deltaTime)
{
Actor::UpdateActor(deltaTime);
-
// Compute new camera from this actor
Vector3 cameraPos = GetPosition();
Vector3 target = GetPosition() + GetForward() * 100.0f;
Vector3 up = Vector3::UnitZ;
-
Matrix4 view = Matrix4::CreateLookAt(cameraPos, target, up);
GetGame()->GetRenderer()->SetViewMatrix(view);
}
@@ -52,7 +49,6 @@ void CameraActor::ActorInput(const uint8_t* keys)
{
angularSpeed += Math::TwoPi;
}
-
- mMoveComp->SetForwardSpeed(forwardSpeed);
- mMoveComp->SetAngularSpeed(angularSpeed);
-}
+ pMoveComp->SetForwardSpeed(forwardSpeed);
+ pMoveComp->SetAngularSpeed(angularSpeed);
+}
\ No newline at end of file
diff --git a/Chapter06/CameraActor.h b/Chapter06/CameraActor.h
index a7e3923c..bfc5df36 100644
--- a/Chapter06/CameraActor.h
+++ b/Chapter06/CameraActor.h
@@ -9,13 +9,12 @@
#pragma once
#include "Actor.h"
-class CameraActor : public Actor
+class CameraActor: public Actor
{
public:
CameraActor(class Game* game);
-
void UpdateActor(float deltaTime) override;
void ActorInput(const uint8_t* keys) override;
private:
- class MoveComponent* mMoveComp;
-};
+ class MoveComponent* pMoveComp;
+};
\ No newline at end of file
diff --git a/Chapter06/CircleComponent.cpp b/Chapter06/CircleComponent.cpp
index 4e40d109..f57bdd8a 100644
--- a/Chapter06/CircleComponent.cpp
+++ b/Chapter06/CircleComponent.cpp
@@ -9,21 +9,18 @@
#include "CircleComponent.h"
#include "Actor.h"
-CircleComponent::CircleComponent(class Actor* owner)
-:Component(owner)
-,mRadius(0.0f)
+CircleComponent::CircleComponent(class Actor* owner): Component(owner), mRadius(0.0f)
{
-
}
const Vector3& CircleComponent::GetCenter() const
{
- return mOwner->GetPosition();
+ return pOwner->GetPosition();
}
float CircleComponent::GetRadius() const
{
- return mOwner->GetScale() * mRadius;
+ return pOwner->GetScale() * mRadius;
}
bool Intersect(const CircleComponent& a, const CircleComponent& b)
@@ -31,10 +28,8 @@ bool Intersect(const CircleComponent& a, const CircleComponent& b)
// Calculate distance squared
Vector3 diff = a.GetCenter() - b.GetCenter();
float distSq = diff.LengthSq();
-
// Calculate sum of radii squared
float radiiSq = a.GetRadius() + b.GetRadius();
radiiSq *= radiiSq;
-
return distSq <= radiiSq;
-}
+}
\ No newline at end of file
diff --git a/Chapter06/CircleComponent.h b/Chapter06/CircleComponent.h
index 61c63ba9..59fbd0a9 100644
--- a/Chapter06/CircleComponent.h
+++ b/Chapter06/CircleComponent.h
@@ -10,17 +10,15 @@
#include "Component.h"
#include "Math.h"
-class CircleComponent : public Component
+class CircleComponent: public Component
{
public:
CircleComponent(class Actor* owner);
-
void SetRadius(float radius) { mRadius = radius; }
float GetRadius() const;
-
const Vector3& GetCenter() const;
private:
float mRadius;
};
-bool Intersect(const CircleComponent& a, const CircleComponent& b);
+bool Intersect(const CircleComponent& a, const CircleComponent& b);
\ No newline at end of file
diff --git a/Chapter06/Component.cpp b/Chapter06/Component.cpp
index c4ed432d..5446d684 100644
--- a/Chapter06/Component.cpp
+++ b/Chapter06/Component.cpp
@@ -9,19 +9,17 @@
#include "Component.h"
#include "Actor.h"
-Component::Component(Actor* owner, int updateOrder)
- :mOwner(owner)
- ,mUpdateOrder(updateOrder)
+Component::Component(Actor* owner, int updateOrder): pOwner(owner), mUpdateOrder(updateOrder)
{
// Add to actor's vector of components
- mOwner->AddComponent(this);
+ pOwner->AddComponent(this);
}
Component::~Component()
{
- mOwner->RemoveComponent(this);
+ pOwner->RemoveComponent(this);
}
void Component::Update(float deltaTime)
{
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Component.h b/Chapter06/Component.h
index e2be424b..1fe03dfe 100644
--- a/Chapter06/Component.h
+++ b/Chapter06/Component.h
@@ -22,12 +22,11 @@ class Component
// Process input for this component
virtual void ProcessInput(const uint8_t* keyState) {}
// Called when world transform changes
- virtual void OnUpdateWorldTransform() { }
-
+ virtual void OnUpdateWorldTransform() {}
int GetUpdateOrder() const { return mUpdateOrder; }
protected:
// Owning actor
- class Actor* mOwner;
+ class Actor* pOwner;
// Update order of component
int mUpdateOrder;
-};
+};
\ No newline at end of file
diff --git a/Chapter06/Game.cpp b/Chapter06/Game.cpp
index cf7e03a7..d2f50fc9 100644
--- a/Chapter06/Game.cpp
+++ b/Chapter06/Game.cpp
@@ -15,12 +15,8 @@
#include "CameraActor.h"
#include "PlaneActor.h"
-Game::Game()
-:mRenderer(nullptr)
-,mIsRunning(true)
-,mUpdatingActors(false)
+Game::Game(): pRenderer(nullptr), mIsRunning(true), mUpdatingActors(false)
{
-
}
bool Game::Initialize()
@@ -30,21 +26,17 @@ bool Game::Initialize()
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
return false;
}
-
// Create the renderer
- mRenderer = new Renderer(this);
- if (!mRenderer->Initialize(1024.0f, 768.0f))
+ pRenderer = new Renderer(this);
+ if (!pRenderer->Initialize(1024.0f, 768.0f))
{
SDL_Log("Failed to initialize renderer");
- delete mRenderer;
- mRenderer = nullptr;
+ delete pRenderer;
+ pRenderer = nullptr;
return false;
}
-
LoadData();
-
mTicksCount = SDL_GetTicks();
-
return true;
}
@@ -70,14 +62,12 @@ void Game::ProcessInput()
break;
}
}
-
const Uint8* state = SDL_GetKeyboardState(NULL);
if (state[SDL_SCANCODE_ESCAPE])
{
mIsRunning = false;
}
-
- for (auto actor : mActors)
+ for (auto actor: mActors)
{
actor->ProcessInput(state);
}
@@ -87,44 +77,38 @@ void Game::UpdateGame()
{
// Compute delta time
// Wait until 16ms has elapsed since last frame
- while (!SDL_TICKS_PASSED(SDL_GetTicks(), mTicksCount + 16))
- ;
-
+ while (!SDL_TICKS_PASSED(SDL_GetTicks(), mTicksCount + 16));
float deltaTime = (SDL_GetTicks() - mTicksCount) / 1000.0f;
if (deltaTime > 0.05f)
{
deltaTime = 0.05f;
}
mTicksCount = SDL_GetTicks();
-
- // Update all actors
+// Update all actors:
mUpdatingActors = true;
- for (auto actor : mActors)
+ for (auto actor: mActors)
{
actor->Update(deltaTime);
}
mUpdatingActors = false;
-
// Move any pending actors to mActors
- for (auto pending : mPendingActors)
+ for (auto pending: mPendingActors)
{
pending->ComputeWorldTransform();
mActors.emplace_back(pending);
}
mPendingActors.clear();
-
// Add any dead actors to a temp vector
std::vector deadActors;
- for (auto actor : mActors)
+ for (auto actor: mActors)
{
if (actor->GetState() == Actor::EDead)
{
deadActors.emplace_back(actor);
}
}
-
// Delete dead actors (which removes them from mActors)
- for (auto actor : deadActors)
+ for (auto actor: deadActors)
{
delete actor;
}
@@ -132,7 +116,7 @@ void Game::UpdateGame()
void Game::GenerateOutput()
{
- mRenderer->Draw();
+ pRenderer->Draw();
}
void Game::LoadData()
@@ -144,15 +128,11 @@ void Game::LoadData()
Quaternion q(Vector3::UnitY, -Math::PiOver2);
q = Quaternion::Concatenate(q, Quaternion(Vector3::UnitZ, Math::Pi + Math::Pi / 4.0f));
a->SetRotation(q);
- MeshComponent* mc = new MeshComponent(a);
- mc->SetMesh(mRenderer->GetMesh("Assets/Cube.gpmesh"));
-
+ MeshComponent* mc = new MeshComponent(a, pRenderer->GetMesh("Assets/Cube.gpmesh"));
a = new Actor(this);
a->SetPosition(Vector3(200.0f, -75.0f, 0.0f));
a->SetScale(3.0f);
- mc = new MeshComponent(a);
- mc->SetMesh(mRenderer->GetMesh("Assets/Sphere.gpmesh"));
-
+ mc = new MeshComponent(a, pRenderer->GetMesh("Assets/Sphere.gpmesh"));
// Setup floor
const float start = -1250.0f;
const float size = 250.0f;
@@ -164,7 +144,6 @@ void Game::LoadData()
a->SetPosition(Vector3(start + i * size, start + j * size, -100.0f));
}
}
-
// Left/right walls
q = Quaternion(Vector3::UnitX, Math::PiOver2);
for (int i = 0; i < 10; i++)
@@ -172,12 +151,10 @@ void Game::LoadData()
a = new PlaneActor(this);
a->SetPosition(Vector3(start + i * size, start - size, 0.0f));
a->SetRotation(q);
-
a = new PlaneActor(this);
a->SetPosition(Vector3(start + i * size, -start + size, 0.0f));
a->SetRotation(q);
}
-
q = Quaternion::Concatenate(q, Quaternion(Vector3::UnitZ, Math::PiOver2));
// Forward/back walls
for (int i = 0; i < 10; i++)
@@ -185,33 +162,61 @@ void Game::LoadData()
a = new PlaneActor(this);
a->SetPosition(Vector3(start - size, start + i * size, 0.0f));
a->SetRotation(q);
-
a = new PlaneActor(this);
a->SetPosition(Vector3(-start + size, start + i * size, 0.0f));
a->SetRotation(q);
}
-
- // Setup lights
- mRenderer->SetAmbientLight(Vector3(0.2f, 0.2f, 0.2f));
- DirectionalLight& dir = mRenderer->GetDirectionalLight();
+// Setup lights:
+ // Directional Light
+ pRenderer->SetAmbientLight(Vector3(0.2f, 0.2f, 0.2f));
+ DirectionalLight& dir = pRenderer->GetDirectionalLight();
dir.mDirection = Vector3(0.0f, -0.707f, -0.707f);
dir.mDiffuseColor = Vector3(0.78f, 0.88f, 1.0f);
dir.mSpecColor = Vector3(0.8f, 0.8f, 0.8f);
-
+ // Point Lights
+ std::vector* plvec = pRenderer->GetPointLights();
+ // Point Light1
+ PointLight pl1;
+ pl1.mWorldPos = Vector3(0.0f, 0.0f, 0.0f);
+ pl1.mDiffuseColor = Vector3(0.0f, 1.0f, 0.0f);
+ pl1.mSpecColor = Vector3(0.0f, 1.0f, 0.0f);
+ pl1.mInnerRadius = 0.0f;
+ pl1.mOuterRadius = 500.0f;
+ plvec->emplace_back(pl1);
+ // Point Light2
+ PointLight pl2;
+ pl2.mWorldPos = Vector3(500.0f, 500.0f, 200.0f);
+ pl2.mDiffuseColor = Vector3(0.0f, 0.0f, 1.0f);
+ pl2.mSpecColor = Vector3(0.0f, 0.0f, 1.0f);
+ pl2.mInnerRadius = 0.0f;
+ pl2.mOuterRadius = 500.0f;
+ plvec->emplace_back(pl2);
+ PointLight pl3;
+ pl3.mWorldPos = Vector3(0.0f, -200.0f, 0.0f);
+ pl3.mDiffuseColor = Vector3(1.0f, 0.0f, 0.0f);
+ pl3.mSpecColor = Vector3(1.0f, 0.0f, 0.0f);
+ pl3.mInnerRadius = 0.0f;
+ pl3.mOuterRadius = 500.0f;
+ plvec->emplace_back(pl3);
+ PointLight pl4;
+ pl4.mWorldPos = Vector3(-1000.0f, 1000.0f, 0.0f);
+ pl4.mDiffuseColor = Vector3(1.0f, 1.0f, 0.0f);
+ pl4.mSpecColor = Vector3(1.0f, 1.0f, 0.0f);
+ pl4.mInnerRadius = 0.0f;
+ pl4.mOuterRadius = 500.0f;
+ plvec->emplace_back(pl4);
// Camera actor
- mCameraActor = new CameraActor(this);
-
+ pCameraActor = new CameraActor(this);
// UI elements
a = new Actor(this);
a->SetPosition(Vector3(-350.0f, -350.0f, 0.0f));
SpriteComponent* sc = new SpriteComponent(a);
- sc->SetTexture(mRenderer->GetTexture("Assets/HealthBar.png"));
-
+ sc->SetTexture(pRenderer->GetTexture("Assets/HealthBar.png"));
a = new Actor(this);
a->SetPosition(Vector3(375.0f, -275.0f, 0.0f));
a->SetScale(0.75f);
sc = new SpriteComponent(a);
- sc->SetTexture(mRenderer->GetTexture("Assets/Radar.png"));
+ sc->SetTexture(pRenderer->GetTexture("Assets/Radar.png"));
}
void Game::UnloadData()
@@ -222,19 +227,18 @@ void Game::UnloadData()
{
delete mActors.back();
}
-
- if (mRenderer)
+ if (pRenderer)
{
- mRenderer->UnloadData();
+ pRenderer->UnloadData();
}
}
void Game::Shutdown()
{
UnloadData();
- if (mRenderer)
+ if (pRenderer)
{
- mRenderer->Shutdown();
+ pRenderer->Shutdown();
}
SDL_Quit();
}
@@ -262,7 +266,6 @@ void Game::RemoveActor(Actor* actor)
std::iter_swap(iter, mPendingActors.end() - 1);
mPendingActors.pop_back();
}
-
// Is it in actors?
iter = std::find(mActors.begin(), mActors.end(), actor);
if (iter != mActors.end())
@@ -271,4 +274,4 @@ void Game::RemoveActor(Actor* actor)
std::iter_swap(iter, mActors.end() - 1);
mActors.pop_back();
}
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Game.h b/Chapter06/Game.h
index 6f567720..dce25038 100644
--- a/Chapter06/Game.h
+++ b/Chapter06/Game.h
@@ -20,30 +20,24 @@ class Game
bool Initialize();
void RunLoop();
void Shutdown();
-
void AddActor(class Actor* actor);
void RemoveActor(class Actor* actor);
-
- class Renderer* GetRenderer() { return mRenderer; }
+ class Renderer* GetRenderer() { return pRenderer; }
private:
void ProcessInput();
void UpdateGame();
void GenerateOutput();
void LoadData();
void UnloadData();
-
// All the actors in the game
std::vector mActors;
// Any pending actors
std::vector mPendingActors;
-
- class Renderer* mRenderer;
-
+ class Renderer* pRenderer;
Uint32 mTicksCount;
bool mIsRunning;
// Track if we're updating actors right now
bool mUpdatingActors;
-
// Game-specific code
- class CameraActor* mCameraActor;
-};
+ class CameraActor* pCameraActor;
+};
\ No newline at end of file
diff --git a/Chapter06/Game.vcxproj b/Chapter06/Game.vcxproj
index ff861c40..a907a695 100644
--- a/Chapter06/Game.vcxproj
+++ b/Chapter06/Game.vcxproj
@@ -57,19 +57,19 @@
{BC508D87-495F-4554-932D-DD68388B63CC}
Win32Proj
Game
- 10.0.16299.0
+ 10.0
Application
true
- v141
+ v143
Unicode
Application
false
- v141
+ v143
true
Unicode
diff --git a/Chapter06/Main.cpp b/Chapter06/Main.cpp
index 22ea0c69..625e0599 100644
--- a/Chapter06/Main.cpp
+++ b/Chapter06/Main.cpp
@@ -18,4 +18,4 @@ int main(int argc, char** argv)
}
game.Shutdown();
return 0;
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Math.cpp b/Chapter06/Math.cpp
index a16e7261..44ff7ddd 100644
--- a/Chapter06/Math.cpp
+++ b/Chapter06/Math.cpp
@@ -39,7 +39,6 @@ static float m4Ident[4][4] =
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
};
-
const Matrix4 Matrix4::Identity(m4Ident);
const Quaternion Quaternion::Identity(0.0f, 0.0f, 0.0f, 1.0f);
@@ -104,33 +103,28 @@ void Matrix4::Invert()
float src[16];
float dst[16];
float det;
-
- // Transpose matrix
+// Transpose matrix:
// row 1 to col 1
src[0] = mat[0][0];
src[4] = mat[0][1];
src[8] = mat[0][2];
src[12] = mat[0][3];
-
// row 2 to col 2
src[1] = mat[1][0];
src[5] = mat[1][1];
src[9] = mat[1][2];
src[13] = mat[1][3];
-
// row 3 to col 3
src[2] = mat[2][0];
src[6] = mat[2][1];
src[10] = mat[2][2];
src[14] = mat[2][3];
-
// row 4 to col 4
src[3] = mat[3][0];
src[7] = mat[3][1];
src[11] = mat[3][2];
src[15] = mat[3][3];
-
- // Calculate cofactors
+// Calculate cofactors:
tmp[0] = src[10] * src[15];
tmp[1] = src[11] * src[14];
tmp[2] = src[9] * src[15];
@@ -143,7 +137,6 @@ void Matrix4::Invert()
tmp[9] = src[10] * src[12];
tmp[10] = src[8] * src[13];
tmp[11] = src[9] * src[12];
-
dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7];
dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7];
dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7];
@@ -160,7 +153,6 @@ void Matrix4::Invert()
dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3];
dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2];
dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2];
-
tmp[0] = src[2] * src[7];
tmp[1] = src[3] * src[6];
tmp[2] = src[1] * src[7];
@@ -173,7 +165,6 @@ void Matrix4::Invert()
tmp[9] = src[2] * src[4];
tmp[10] = src[0] * src[5];
tmp[11] = src[1] * src[4];
-
dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15];
dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15];
dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15];
@@ -190,17 +181,14 @@ void Matrix4::Invert()
dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9];
dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9];
dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8];
-
// Calculate determinant
det = src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3] * dst[3];
-
// Inverse of matrix is divided by determinant
det = 1 / det;
for (int j = 0; j < 16; j++)
{
dst[j] *= det;
}
-
// Set it back
for (int i = 0; i < 4; i++)
{
@@ -214,26 +202,21 @@ void Matrix4::Invert()
Matrix4 Matrix4::CreateFromQuaternion(const class Quaternion& q)
{
float mat[4][4];
-
mat[0][0] = 1.0f - 2.0f * q.y * q.y - 2.0f * q.z * q.z;
mat[0][1] = 2.0f * q.x * q.y + 2.0f * q.w * q.z;
mat[0][2] = 2.0f * q.x * q.z - 2.0f * q.w * q.y;
mat[0][3] = 0.0f;
-
mat[1][0] = 2.0f * q.x * q.y - 2.0f * q.w * q.z;
mat[1][1] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.z * q.z;
mat[1][2] = 2.0f * q.y * q.z + 2.0f * q.w * q.x;
mat[1][3] = 0.0f;
-
mat[2][0] = 2.0f * q.x * q.z + 2.0f * q.w * q.y;
mat[2][1] = 2.0f * q.y * q.z - 2.0f * q.w * q.x;
mat[2][2] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.y * q.y;
mat[2][3] = 0.0f;
-
mat[3][0] = 0.0f;
mat[3][1] = 0.0f;
mat[3][2] = 0.0f;
mat[3][3] = 1.0f;
-
return Matrix4(mat);
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Math.h b/Chapter06/Math.h
index 752963f1..53d8f0b8 100644
--- a/Chapter06/Math.h
+++ b/Chapter06/Math.h
@@ -24,12 +24,10 @@ namespace Math
{
return degrees * Pi / 180.0f;
}
-
inline float ToDegrees(float radians)
{
return radians * 180.0f / Pi;
}
-
inline bool NearZero(float val, float epsilon = 0.001f)
{
if (fabs(val) <= epsilon)
@@ -41,70 +39,57 @@ namespace Math
return false;
}
}
-
template
T Max(const T& a, const T& b)
{
return (a < b ? b : a);
}
-
template
T Min(const T& a, const T& b)
{
return (a < b ? a : b);
}
-
template
T Clamp(const T& value, const T& lower, const T& upper)
{
return Min(upper, Max(lower, value));
}
-
inline float Abs(float value)
{
return fabs(value);
}
-
inline float Cos(float angle)
{
return cosf(angle);
}
-
inline float Sin(float angle)
{
return sinf(angle);
}
-
inline float Tan(float angle)
{
return tanf(angle);
}
-
inline float Acos(float value)
{
return acosf(value);
}
-
inline float Atan2(float y, float x)
{
return atan2f(y, x);
}
-
inline float Cot(float angle)
{
return 1.0f / Tan(angle);
}
-
inline float Lerp(float a, float b, float f)
{
return a + f * (b - a);
}
-
inline float Sqrt(float value)
{
return sqrtf(value);
}
-
inline float Fmod(float numer, float denom)
{
return fmod(numer, denom);
@@ -118,54 +103,41 @@ class Vector2
float x;
float y;
- Vector2()
- :x(0.0f)
- ,y(0.0f)
+ Vector2(): x(0.0f), y(0.0f)
{}
-
- explicit Vector2(float inX, float inY)
- :x(inX)
- ,y(inY)
+ explicit Vector2(float inX, float inY): x(inX), y(inY)
{}
-
// Set both components in one line
void Set(float inX, float inY)
{
x = inX;
y = inY;
}
-
// Vector addition (a + b)
friend Vector2 operator+(const Vector2& a, const Vector2& b)
{
return Vector2(a.x + b.x, a.y + b.y);
}
-
// Vector subtraction (a - b)
friend Vector2 operator-(const Vector2& a, const Vector2& b)
{
return Vector2(a.x - b.x, a.y - b.y);
}
-
// Component-wise multiplication
- // (a.x * b.x, ...)
friend Vector2 operator*(const Vector2& a, const Vector2& b)
{
return Vector2(a.x * b.x, a.y * b.y);
}
-
// Scalar multiplication
friend Vector2 operator*(const Vector2& vec, float scalar)
{
return Vector2(vec.x * scalar, vec.y * scalar);
}
-
// Scalar multiplication
friend Vector2 operator*(float scalar, const Vector2& vec)
{
return Vector2(vec.x * scalar, vec.y * scalar);
}
-
// Scalar *=
Vector2& operator*=(float scalar)
{
@@ -173,7 +145,6 @@ class Vector2
y *= scalar;
return *this;
}
-
// Vector +=
Vector2& operator+=(const Vector2& right)
{
@@ -181,7 +152,6 @@ class Vector2
y += right.y;
return *this;
}
-
// Vector -=
Vector2& operator-=(const Vector2& right)
{
@@ -189,19 +159,16 @@ class Vector2
y -= right.y;
return *this;
}
-
// Length squared of vector
float LengthSq() const
{
return (x*x + y*y);
}
-
// Length of vector
float Length() const
{
return (Math::Sqrt(LengthSq()));
}
-
// Normalize this vector
void Normalize()
{
@@ -209,7 +176,6 @@ class Vector2
x /= length;
y /= length;
}
-
// Normalize the provided vector
static Vector2 Normalize(const Vector2& vec)
{
@@ -217,25 +183,21 @@ class Vector2
temp.Normalize();
return temp;
}
-
// Dot product between two vectors (a dot b)
static float Dot(const Vector2& a, const Vector2& b)
{
return (a.x * b.x + a.y * b.y);
}
-
// Lerp from A to B by f
static Vector2 Lerp(const Vector2& a, const Vector2& b, float f)
{
return Vector2(a + f * (b - a));
}
-
// Reflect V about (normalized) N
static Vector2 Reflect(const Vector2& v, const Vector2& n)
{
return v - 2.0f * Vector2::Dot(v, n) * n;
}
-
// Transform vector by matrix
static Vector2 Transform(const Vector2& vec, const class Matrix3& mat, float w = 1.0f);
@@ -254,24 +216,15 @@ class Vector3
float y;
float z;
- Vector3()
- :x(0.0f)
- ,y(0.0f)
- ,z(0.0f)
+ Vector3(): x(0.0f), y(0.0f), z(0.0f)
{}
-
- explicit Vector3(float inX, float inY, float inZ)
- :x(inX)
- ,y(inY)
- ,z(inZ)
+ explicit Vector3(float inX, float inY, float inZ): x(inX), y(inY), z(inZ)
{}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&x);
}
-
// Set all three components in one line
void Set(float inX, float inY, float inZ)
{
@@ -279,37 +232,31 @@ class Vector3
y = inY;
z = inZ;
}
-
// Vector addition (a + b)
friend Vector3 operator+(const Vector3& a, const Vector3& b)
{
return Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
}
-
// Vector subtraction (a - b)
friend Vector3 operator-(const Vector3& a, const Vector3& b)
{
return Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
}
-
// Component-wise multiplication
friend Vector3 operator*(const Vector3& left, const Vector3& right)
{
return Vector3(left.x * right.x, left.y * right.y, left.z * right.z);
}
-
// Scalar multiplication
friend Vector3 operator*(const Vector3& vec, float scalar)
{
return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
}
-
// Scalar multiplication
friend Vector3 operator*(float scalar, const Vector3& vec)
{
return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
}
-
// Scalar *=
Vector3& operator*=(float scalar)
{
@@ -318,7 +265,6 @@ class Vector3
z *= scalar;
return *this;
}
-
// Vector +=
Vector3& operator+=(const Vector3& right)
{
@@ -327,7 +273,6 @@ class Vector3
z += right.z;
return *this;
}
-
// Vector -=
Vector3& operator-=(const Vector3& right)
{
@@ -336,19 +281,16 @@ class Vector3
z -= right.z;
return *this;
}
-
// Length squared of vector
float LengthSq() const
{
return (x*x + y*y + z*z);
}
-
// Length of vector
float Length() const
{
return (Math::Sqrt(LengthSq()));
}
-
// Normalize this vector
void Normalize()
{
@@ -357,7 +299,6 @@ class Vector3
y /= length;
z /= length;
}
-
// Normalize the provided vector
static Vector3 Normalize(const Vector3& vec)
{
@@ -365,13 +306,11 @@ class Vector3
temp.Normalize();
return temp;
}
-
// Dot product between two vectors (a dot b)
static float Dot(const Vector3& a, const Vector3& b)
{
return (a.x * b.x + a.y * b.y + a.z * b.z);
}
-
// Cross product between two vectors (a cross b)
static Vector3 Cross(const Vector3& a, const Vector3& b)
{
@@ -381,23 +320,19 @@ class Vector3
temp.z = a.x * b.y - a.y * b.x;
return temp;
}
-
// Lerp from A to B by f
static Vector3 Lerp(const Vector3& a, const Vector3& b, float f)
{
return Vector3(a + f * (b - a));
}
-
// Reflect V about (normalized) N
static Vector3 Reflect(const Vector3& v, const Vector3& n)
{
return v - 2.0f * Vector3::Dot(v, n) * n;
}
-
static Vector3 Transform(const Vector3& vec, const class Matrix4& mat, float w = 1.0f);
// This will transform the vector and renormalize the w component
static Vector3 TransformWithPerspDiv(const Vector3& vec, const class Matrix4& mat, float w = 1.0f);
-
// Transform a Vector3 by a quaternion
static Vector3 Transform(const Vector3& v, const class Quaternion& q);
@@ -422,18 +357,15 @@ class Matrix3
{
*this = Matrix3::Identity;
}
-
explicit Matrix3(float inMat[3][3])
{
memcpy(mat, inMat, 9 * sizeof(float));
}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&mat[0][0]);
}
-
// Matrix multiplication
friend Matrix3 operator*(const Matrix3& left, const Matrix3& right)
{
@@ -443,49 +375,40 @@ class Matrix3
left.mat[0][0] * right.mat[0][0] +
left.mat[0][1] * right.mat[1][0] +
left.mat[0][2] * right.mat[2][0];
-
retVal.mat[0][1] =
left.mat[0][0] * right.mat[0][1] +
left.mat[0][1] * right.mat[1][1] +
left.mat[0][2] * right.mat[2][1];
-
retVal.mat[0][2] =
left.mat[0][0] * right.mat[0][2] +
left.mat[0][1] * right.mat[1][2] +
left.mat[0][2] * right.mat[2][2];
-
// row 1
retVal.mat[1][0] =
left.mat[1][0] * right.mat[0][0] +
left.mat[1][1] * right.mat[1][0] +
left.mat[1][2] * right.mat[2][0];
-
retVal.mat[1][1] =
left.mat[1][0] * right.mat[0][1] +
left.mat[1][1] * right.mat[1][1] +
left.mat[1][2] * right.mat[2][1];
-
retVal.mat[1][2] =
left.mat[1][0] * right.mat[0][2] +
left.mat[1][1] * right.mat[1][2] +
left.mat[1][2] * right.mat[2][2];
-
// row 2
retVal.mat[2][0] =
left.mat[2][0] * right.mat[0][0] +
left.mat[2][1] * right.mat[1][0] +
left.mat[2][2] * right.mat[2][0];
-
retVal.mat[2][1] =
left.mat[2][0] * right.mat[0][1] +
left.mat[2][1] * right.mat[1][1] +
left.mat[2][2] * right.mat[2][1];
-
retVal.mat[2][2] =
left.mat[2][0] * right.mat[0][2] +
left.mat[2][1] * right.mat[1][2] +
left.mat[2][2] * right.mat[2][2];
-
return retVal;
}
@@ -556,18 +479,15 @@ class Matrix4
{
*this = Matrix4::Identity;
}
-
explicit Matrix4(float inMat[4][4])
{
memcpy(mat, inMat, 16 * sizeof(float));
}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&mat[0][0]);
}
-
// Matrix multiplication (a * b)
friend Matrix4 operator*(const Matrix4& a, const Matrix4& b)
{
@@ -578,136 +498,113 @@ class Matrix4
a.mat[0][1] * b.mat[1][0] +
a.mat[0][2] * b.mat[2][0] +
a.mat[0][3] * b.mat[3][0];
-
retVal.mat[0][1] =
a.mat[0][0] * b.mat[0][1] +
a.mat[0][1] * b.mat[1][1] +
a.mat[0][2] * b.mat[2][1] +
a.mat[0][3] * b.mat[3][1];
-
retVal.mat[0][2] =
a.mat[0][0] * b.mat[0][2] +
a.mat[0][1] * b.mat[1][2] +
a.mat[0][2] * b.mat[2][2] +
a.mat[0][3] * b.mat[3][2];
-
retVal.mat[0][3] =
a.mat[0][0] * b.mat[0][3] +
a.mat[0][1] * b.mat[1][3] +
a.mat[0][2] * b.mat[2][3] +
a.mat[0][3] * b.mat[3][3];
-
// row 1
retVal.mat[1][0] =
a.mat[1][0] * b.mat[0][0] +
a.mat[1][1] * b.mat[1][0] +
a.mat[1][2] * b.mat[2][0] +
a.mat[1][3] * b.mat[3][0];
-
retVal.mat[1][1] =
a.mat[1][0] * b.mat[0][1] +
a.mat[1][1] * b.mat[1][1] +
a.mat[1][2] * b.mat[2][1] +
a.mat[1][3] * b.mat[3][1];
-
retVal.mat[1][2] =
a.mat[1][0] * b.mat[0][2] +
a.mat[1][1] * b.mat[1][2] +
a.mat[1][2] * b.mat[2][2] +
a.mat[1][3] * b.mat[3][2];
-
retVal.mat[1][3] =
a.mat[1][0] * b.mat[0][3] +
a.mat[1][1] * b.mat[1][3] +
a.mat[1][2] * b.mat[2][3] +
a.mat[1][3] * b.mat[3][3];
-
// row 2
retVal.mat[2][0] =
a.mat[2][0] * b.mat[0][0] +
a.mat[2][1] * b.mat[1][0] +
a.mat[2][2] * b.mat[2][0] +
a.mat[2][3] * b.mat[3][0];
-
retVal.mat[2][1] =
a.mat[2][0] * b.mat[0][1] +
a.mat[2][1] * b.mat[1][1] +
a.mat[2][2] * b.mat[2][1] +
a.mat[2][3] * b.mat[3][1];
-
retVal.mat[2][2] =
a.mat[2][0] * b.mat[0][2] +
a.mat[2][1] * b.mat[1][2] +
a.mat[2][2] * b.mat[2][2] +
a.mat[2][3] * b.mat[3][2];
-
retVal.mat[2][3] =
a.mat[2][0] * b.mat[0][3] +
a.mat[2][1] * b.mat[1][3] +
a.mat[2][2] * b.mat[2][3] +
a.mat[2][3] * b.mat[3][3];
-
// row 3
retVal.mat[3][0] =
a.mat[3][0] * b.mat[0][0] +
a.mat[3][1] * b.mat[1][0] +
a.mat[3][2] * b.mat[2][0] +
a.mat[3][3] * b.mat[3][0];
-
retVal.mat[3][1] =
a.mat[3][0] * b.mat[0][1] +
a.mat[3][1] * b.mat[1][1] +
a.mat[3][2] * b.mat[2][1] +
a.mat[3][3] * b.mat[3][1];
-
retVal.mat[3][2] =
a.mat[3][0] * b.mat[0][2] +
a.mat[3][1] * b.mat[1][2] +
a.mat[3][2] * b.mat[2][2] +
a.mat[3][3] * b.mat[3][2];
-
retVal.mat[3][3] =
a.mat[3][0] * b.mat[0][3] +
a.mat[3][1] * b.mat[1][3] +
a.mat[3][2] * b.mat[2][3] +
a.mat[3][3] * b.mat[3][3];
-
return retVal;
}
-
Matrix4& operator*=(const Matrix4& right)
{
*this = *this * right;
return *this;
}
-
// Invert the matrix - super slow
void Invert();
-
// Get the translation component of the matrix
Vector3 GetTranslation() const
{
return Vector3(mat[3][0], mat[3][1], mat[3][2]);
}
-
// Get the X axis of the matrix (forward)
Vector3 GetXAxis() const
{
return Vector3::Normalize(Vector3(mat[0][0], mat[0][1], mat[0][2]));
}
-
// Get the Y axis of the matrix (left)
Vector3 GetYAxis() const
{
return Vector3::Normalize(Vector3(mat[1][0], mat[1][1], mat[1][2]));
}
-
// Get the Z axis of the matrix (up)
Vector3 GetZAxis() const
{
return Vector3::Normalize(Vector3(mat[2][0], mat[2][1], mat[2][2]));
}
-
// Extract the scale component from the matrix
Vector3 GetScale() const
{
@@ -717,7 +614,6 @@ class Matrix4
retVal.z = Vector3(mat[2][0], mat[2][1], mat[2][2]).Length();
return retVal;
}
-
// Create a scale matrix with x, y, and z scales
static Matrix4 CreateScale(float xScale, float yScale, float zScale)
{
@@ -730,18 +626,15 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateScale(const Vector3& scaleVector)
{
return CreateScale(scaleVector.x, scaleVector.y, scaleVector.z);
}
-
// Create a scale matrix with a uniform factor
static Matrix4 CreateScale(float scale)
{
return CreateScale(scale, scale, scale);
}
-
// Rotation about x-axis
static Matrix4 CreateRotationX(float theta)
{
@@ -754,7 +647,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Rotation about y-axis
static Matrix4 CreateRotationY(float theta)
{
@@ -767,7 +659,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Rotation about z-axis
static Matrix4 CreateRotationZ(float theta)
{
@@ -780,10 +671,8 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Create a rotation matrix from a quaternion
static Matrix4 CreateFromQuaternion(const class Quaternion& q);
-
static Matrix4 CreateTranslation(const Vector3& trans)
{
float temp[4][4] =
@@ -795,7 +684,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
{
Vector3 zaxis = Vector3::Normalize(target - eye);
@@ -805,7 +693,6 @@ class Matrix4
trans.x = -Vector3::Dot(xaxis, eye);
trans.y = -Vector3::Dot(yaxis, eye);
trans.z = -Vector3::Dot(zaxis, eye);
-
float temp[4][4] =
{
{ xaxis.x, yaxis.x, zaxis.x, 0.0f },
@@ -815,7 +702,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateOrtho(float width, float height, float near, float far)
{
float temp[4][4] =
@@ -827,7 +713,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreatePerspectiveFOV(float fovY, float width, float height, float near, float far)
{
float yScale = Math::Cot(fovY / 2.0f);
@@ -841,7 +726,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Create "Simple" View-Projection Matrix from Chapter 6
static Matrix4 CreateSimpleViewProj(float width, float height)
{
@@ -871,17 +755,13 @@ class Quaternion
{
*this = Quaternion::Identity;
}
-
- // This directly sets the quaternion components --
- // don't use for axis/angle
+ // This directly sets the quaternion components -- don't use for axis/angle
explicit Quaternion(float inX, float inY, float inZ, float inW)
{
Set(inX, inY, inZ, inW);
}
-
// Construct the quaternion from an axis and angle
- // It is assumed that axis is already normalized,
- // and the angle is in radians
+ // It is assumed that axis is already normalized, and the angle is in radians
explicit Quaternion(const Vector3& axis, float angle)
{
float scalar = Math::Sin(angle / 2.0f);
@@ -890,7 +770,6 @@ class Quaternion
z = axis.z * scalar;
w = Math::Cos(angle / 2.0f);
}
-
// Directly set the internal components
void Set(float inX, float inY, float inZ, float inW)
{
@@ -899,24 +778,20 @@ class Quaternion
z = inZ;
w = inW;
}
-
void Conjugate()
{
x *= -1.0f;
y *= -1.0f;
z *= -1.0f;
}
-
float LengthSq() const
{
return (x*x + y*y + z*z + w*w);
}
-
float Length() const
{
return Math::Sqrt(LengthSq());
}
-
void Normalize()
{
float length = Length();
@@ -925,7 +800,6 @@ class Quaternion
z /= length;
w /= length;
}
-
// Normalize the provided quaternion
static Quaternion Normalize(const Quaternion& q)
{
@@ -933,7 +807,6 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
// Linear interpolation
static Quaternion Lerp(const Quaternion& a, const Quaternion& b, float f)
{
@@ -945,25 +818,20 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
static float Dot(const Quaternion& a, const Quaternion& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}
-
// Spherical Linear Interpolation
static Quaternion Slerp(const Quaternion& a, const Quaternion& b, float f)
{
float rawCosm = Quaternion::Dot(a, b);
-
float cosom = -rawCosm;
if (rawCosm >= 0.0f)
{
cosom = rawCosm;
}
-
float scale0, scale1;
-
if (cosom < 0.9999f)
{
const float omega = Math::Acos(cosom);
@@ -973,17 +841,14 @@ class Quaternion
}
else
{
- // Use linear interpolation if the quaternions
- // are collinear
+ // Use linear interpolation if the quaternions are collinear
scale0 = 1.0f - f;
scale1 = f;
}
-
if (rawCosm < 0.0f)
{
scale1 = -scale1;
}
-
Quaternion retVal;
retVal.x = scale0 * a.x + scale1 * b.x;
retVal.y = scale0 * a.y + scale1 * b.y;
@@ -992,13 +857,11 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
// Concatenate
// Rotate by q FOLLOWED BY p
static Quaternion Concatenate(const Quaternion& q, const Quaternion& p)
{
Quaternion retVal;
-
// Vector component is:
// ps * qv + qs * pv + pv x qv
Vector3 qv(q.x, q.y, q.z);
@@ -1007,11 +870,9 @@ class Quaternion
retVal.x = newVec.x;
retVal.y = newVec.y;
retVal.z = newVec.z;
-
// Scalar component is:
// ps * qs - pv . qv
retVal.w = p.w * q.w - Vector3::Dot(pv, qv);
-
return retVal;
}
@@ -1030,4 +891,4 @@ namespace Color
static const Vector3 LightBlue(0.68f, 0.85f, 0.9f);
static const Vector3 LightPink(1.0f, 0.71f, 0.76f);
static const Vector3 LightGreen(0.56f, 0.93f, 0.56f);
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Mesh.cpp b/Chapter06/Mesh.cpp
index 1673b2b2..fe292d4c 100644
--- a/Chapter06/Mesh.cpp
+++ b/Chapter06/Mesh.cpp
@@ -16,10 +16,7 @@
#include
#include "Math.h"
-Mesh::Mesh()
- :mVertexArray(nullptr)
- ,mRadius(0.0f)
- ,mSpecPower(100.0f)
+Mesh::Mesh(): mVertexArray(nullptr), mRadius(0.0f), mSpecPower(100.0f)
{
}
@@ -35,35 +32,28 @@ bool Mesh::Load(const std::string & fileName, Renderer* renderer)
SDL_Log("File not found: Mesh %s", fileName.c_str());
return false;
}
-
std::stringstream fileStream;
fileStream << file.rdbuf();
std::string contents = fileStream.str();
rapidjson::StringStream jsonStr(contents.c_str());
rapidjson::Document doc;
doc.ParseStream(jsonStr);
-
if (!doc.IsObject())
{
SDL_Log("Mesh %s is not valid json", fileName.c_str());
return false;
}
-
int ver = doc["version"].GetInt();
-
// Check the version
if (ver != 1)
{
SDL_Log("Mesh %s not version 1", fileName.c_str());
return false;
}
-
mShaderName = doc["shader"].GetString();
-
// Skip the vertex format/shader for now
// (This is changed in a later chapter's code)
size_t vertSize = 8;
-
// Load textures
const rapidjson::Value& textures = doc["textures"];
if (!textures.IsArray() || textures.Size() < 1)
@@ -71,9 +61,7 @@ bool Mesh::Load(const std::string & fileName, Renderer* renderer)
SDL_Log("Mesh %s has no textures, there should be at least one", fileName.c_str());
return false;
}
-
mSpecPower = static_cast(doc["specularPower"].GetDouble());
-
for (rapidjson::SizeType i = 0; i < textures.Size(); i++)
{
// Is this texture already loaded?
@@ -91,7 +79,6 @@ bool Mesh::Load(const std::string & fileName, Renderer* renderer)
}
mTextures.emplace_back(t);
}
-
// Load in the vertices
const rapidjson::Value& vertsJson = doc["vertices"];
if (!vertsJson.IsArray() || vertsJson.Size() < 1)
@@ -99,7 +86,6 @@ bool Mesh::Load(const std::string & fileName, Renderer* renderer)
SDL_Log("Mesh %s has no vertices", fileName.c_str());
return false;
}
-
std::vector vertices;
vertices.reserve(vertsJson.Size() * vertSize);
mRadius = 0.0f;
@@ -112,20 +98,16 @@ bool Mesh::Load(const std::string & fileName, Renderer* renderer)
SDL_Log("Unexpected vertex format for %s", fileName.c_str());
return false;
}
-
Vector3 pos(vert[0].GetDouble(), vert[1].GetDouble(), vert[2].GetDouble());
mRadius = Math::Max(mRadius, pos.LengthSq());
-
// Add the floats
for (rapidjson::SizeType i = 0; i < vert.Size(); i++)
{
vertices.emplace_back(static_cast(vert[i].GetDouble()));
}
}
-
// We were computing length squared earlier
mRadius = Math::Sqrt(mRadius);
-
// Load in the indices
const rapidjson::Value& indJson = doc["indices"];
if (!indJson.IsArray() || indJson.Size() < 1)
@@ -133,7 +115,6 @@ bool Mesh::Load(const std::string & fileName, Renderer* renderer)
SDL_Log("Mesh %s has no indices", fileName.c_str());
return false;
}
-
std::vector indices;
indices.reserve(indJson.Size() * 3);
for (rapidjson::SizeType i = 0; i < indJson.Size(); i++)
@@ -144,15 +125,12 @@ bool Mesh::Load(const std::string & fileName, Renderer* renderer)
SDL_Log("Invalid indices for %s", fileName.c_str());
return false;
}
-
indices.emplace_back(ind[0].GetUint());
indices.emplace_back(ind[1].GetUint());
indices.emplace_back(ind[2].GetUint());
}
-
// Now create a vertex array
- mVertexArray = new VertexArray(vertices.data(), static_cast(vertices.size()) / vertSize,
- indices.data(), static_cast(indices.size()));
+ mVertexArray = new VertexArray(vertices.data(), static_cast(vertices.size()) / vertSize, indices.data(), static_cast(indices.size()));
return true;
}
@@ -172,4 +150,4 @@ Texture* Mesh::GetTexture(size_t index)
{
return nullptr;
}
-}
+}
\ No newline at end of file
diff --git a/Chapter06/MeshComponent.cpp b/Chapter06/MeshComponent.cpp
index 1f4cbdb2..4df13170 100644
--- a/Chapter06/MeshComponent.cpp
+++ b/Chapter06/MeshComponent.cpp
@@ -8,24 +8,20 @@
#include "MeshComponent.h"
#include "Shader.h"
-#include "Mesh.h"
#include "Actor.h"
#include "Game.h"
#include "Renderer.h"
#include "Texture.h"
#include "VertexArray.h"
-MeshComponent::MeshComponent(Actor* owner)
- :Component(owner)
- ,mMesh(nullptr)
- ,mTextureIndex(0)
+MeshComponent::MeshComponent(Actor* owner, class Mesh* mesh): Component(owner), mMesh(mesh), mTextureIndex(0)
{
- mOwner->GetGame()->GetRenderer()->AddMeshComp(this);
+ pOwner->GetGame()->GetRenderer()->AddMeshComp(this);
}
MeshComponent::~MeshComponent()
{
- mOwner->GetGame()->GetRenderer()->RemoveMeshComp(this);
+ pOwner->GetGame()->GetRenderer()->RemoveMeshComp(this);
}
void MeshComponent::Draw(Shader* shader)
@@ -33,8 +29,7 @@ void MeshComponent::Draw(Shader* shader)
if (mMesh)
{
// Set the world transform
- shader->SetMatrixUniform("uWorldTransform",
- mOwner->GetWorldTransform());
+ shader->SetMatrixUniform("uWorldTransform", pOwner->GetWorldTransform());
// Set specular power
shader->SetFloatUniform("uSpecPower", mMesh->GetSpecPower());
// Set the active texture
@@ -49,4 +44,4 @@ void MeshComponent::Draw(Shader* shader)
// Draw
glDrawElements(GL_TRIANGLES, va->GetNumIndices(), GL_UNSIGNED_INT, nullptr);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter06/MeshComponent.h b/Chapter06/MeshComponent.h
index 48765568..52d49ba8 100644
--- a/Chapter06/MeshComponent.h
+++ b/Chapter06/MeshComponent.h
@@ -9,18 +9,21 @@
#pragma once
#include "Component.h"
#include
+#include "Mesh.h"
-class MeshComponent : public Component
+class MeshComponent: public Component
{
public:
- MeshComponent(class Actor* owner);
+ MeshComponent(class Actor* owner, class Mesh* mesh);
~MeshComponent();
// Draw this mesh component
virtual void Draw(class Shader* shader);
// Set the mesh/texture index used by mesh component
virtual void SetMesh(class Mesh* mesh) { mMesh = mesh; }
+ // Get name of shader
+ inline const std::string& GetShaderName() const { return mMesh->GetShaderName(); }
void SetTextureIndex(size_t index) { mTextureIndex = index; }
protected:
class Mesh* mMesh;
size_t mTextureIndex;
-};
+};
\ No newline at end of file
diff --git a/Chapter06/MoveComponent.cpp b/Chapter06/MoveComponent.cpp
index 5b51c6fc..8b96a42c 100644
--- a/Chapter06/MoveComponent.cpp
+++ b/Chapter06/MoveComponent.cpp
@@ -9,32 +9,27 @@
#include "MoveComponent.h"
#include "Actor.h"
-MoveComponent::MoveComponent(class Actor* owner, int updateOrder)
-:Component(owner, updateOrder)
-,mAngularSpeed(0.0f)
-,mForwardSpeed(0.0f)
+MoveComponent::MoveComponent(class Actor* owner, int updateOrder): Component(owner, updateOrder), mAngularSpeed(0.0f), mForwardSpeed(0.0f)
{
-
}
void MoveComponent::Update(float deltaTime)
{
if (!Math::NearZero(mAngularSpeed))
{
- Quaternion rot = mOwner->GetRotation();
+ Quaternion rot = pOwner->GetRotation();
float angle = mAngularSpeed * deltaTime;
// Create quaternion for incremental rotation
// (Rotate about up axis)
Quaternion inc(Vector3::UnitZ, angle);
// Concatenate old and new quaternion
rot = Quaternion::Concatenate(rot, inc);
- mOwner->SetRotation(rot);
+ pOwner->SetRotation(rot);
}
-
if (!Math::NearZero(mForwardSpeed))
{
- Vector3 pos = mOwner->GetPosition();
- pos += mOwner->GetForward() * mForwardSpeed * deltaTime;
- mOwner->SetPosition(pos);
+ Vector3 pos = pOwner->GetPosition();
+ pos += pOwner->GetForward() * mForwardSpeed * deltaTime;
+ pOwner->SetPosition(pos);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter06/MoveComponent.h b/Chapter06/MoveComponent.h
index def7d389..c737e66b 100644
--- a/Chapter06/MoveComponent.h
+++ b/Chapter06/MoveComponent.h
@@ -9,13 +9,12 @@
#pragma once
#include "Component.h"
-class MoveComponent : public Component
+class MoveComponent: public Component
{
public:
// Lower update order to update first
MoveComponent(class Actor* owner, int updateOrder = 10);
void Update(float deltaTime) override;
-
float GetAngularSpeed() const { return mAngularSpeed; }
float GetForwardSpeed() const { return mForwardSpeed; }
void SetAngularSpeed(float speed) { mAngularSpeed = speed; }
@@ -23,4 +22,4 @@ class MoveComponent : public Component
private:
float mAngularSpeed;
float mForwardSpeed;
-};
+};
\ No newline at end of file
diff --git a/Chapter06/PlaneActor.cpp b/Chapter06/PlaneActor.cpp
index 5398ca4c..bfaa3c4b 100644
--- a/Chapter06/PlaneActor.cpp
+++ b/Chapter06/PlaneActor.cpp
@@ -11,10 +11,8 @@
#include "Renderer.h"
#include "MeshComponent.h"
-PlaneActor::PlaneActor(Game* game)
- :Actor(game)
+PlaneActor::PlaneActor(Game* game): Actor(game)
{
SetScale(10.0f);
- MeshComponent* mc = new MeshComponent(this);
- mc->SetMesh(GetGame()->GetRenderer()->GetMesh("Assets/Plane.gpmesh"));
-}
+ MeshComponent* mc = new MeshComponent(this, game->GetRenderer()->GetMesh("Assets/Plane.gpmesh"));
+}
\ No newline at end of file
diff --git a/Chapter06/PlaneActor.h b/Chapter06/PlaneActor.h
index 8187b64a..ca323e87 100644
--- a/Chapter06/PlaneActor.h
+++ b/Chapter06/PlaneActor.h
@@ -9,7 +9,7 @@
#pragma once
#include "Actor.h"
-class PlaneActor : public Actor
+class PlaneActor: public Actor
{
public:
PlaneActor(class Game* game);
diff --git a/Chapter06/Renderer.cpp b/Chapter06/Renderer.cpp
index 43a25fe8..72674ad2 100644
--- a/Chapter06/Renderer.cpp
+++ b/Chapter06/Renderer.cpp
@@ -16,10 +16,7 @@
#include "MeshComponent.h"
#include
-Renderer::Renderer(Game* game)
- :mGame(game)
- ,mSpriteShader(nullptr)
- ,mMeshShader(nullptr)
+Renderer::Renderer(Game* game): pGame(game), pCurrentShader(nullptr)
{
}
@@ -31,7 +28,6 @@ bool Renderer::Initialize(float screenWidth, float screenHeight)
{
mScreenWidth = screenWidth;
mScreenHeight = screenHeight;
-
// Set OpenGL attributes
// Use the core OpenGL profile
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
@@ -48,18 +44,14 @@ bool Renderer::Initialize(float screenWidth, float screenHeight)
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// Force OpenGL to use hardware acceleration
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
-
- mWindow = SDL_CreateWindow("Game Programming in C++ (Chapter 6)", 100, 100,
- static_cast(mScreenWidth), static_cast(mScreenHeight), SDL_WINDOW_OPENGL);
- if (!mWindow)
+ pWindow = SDL_CreateWindow("Game Programming in C++ (Chapter 6)", 100, 100, static_cast(mScreenWidth), static_cast(mScreenHeight), SDL_WINDOW_OPENGL);
+ if (!pWindow)
{
SDL_Log("Failed to create window: %s", SDL_GetError());
return false;
}
-
// Create an OpenGL context
- mContext = SDL_GL_CreateContext(mWindow);
-
+ mContext = SDL_GL_CreateContext(pWindow);
// Initialize GLEW
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
@@ -67,33 +59,25 @@ bool Renderer::Initialize(float screenWidth, float screenHeight)
SDL_Log("Failed to initialize GLEW.");
return false;
}
-
- // On some platforms, GLEW will emit a benign error code,
- // so clear it
+ // On some platforms, GLEW will emit a benign error code, so clear it
glGetError();
-
// Make sure we can create/compile shaders
if (!LoadShaders())
{
SDL_Log("Failed to load shaders.");
return false;
}
-
// Create quad for drawing sprites
CreateSpriteVerts();
-
return true;
}
void Renderer::Shutdown()
{
- delete mSpriteVerts;
- mSpriteShader->Unload();
- delete mSpriteShader;
- mMeshShader->Unload();
- delete mMeshShader;
+ delete pSpriteVerts;
+ pSpriteVerts = nullptr;
SDL_GL_DeleteContext(mContext);
- SDL_DestroyWindow(mWindow);
+ SDL_DestroyWindow(pWindow);
}
void Renderer::UnloadData()
@@ -105,7 +89,6 @@ void Renderer::UnloadData()
delete i.second;
}
mTextures.clear();
-
// Destroy meshes
for (auto i : mMeshes)
{
@@ -113,30 +96,41 @@ void Renderer::UnloadData()
delete i.second;
}
mMeshes.clear();
+ // Destroy shaders
+ for (auto i : mShaders)
+ {
+ i.second->Unload();
+ delete i.second;
+ }
+ mShaders.clear();
}
void Renderer::Draw()
{
- // Set the clear color to light grey
+ // Set the clear color to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
// Draw mesh components
// Enable depth buffering/disable alpha blend
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
// Set the mesh shader active
- mMeshShader->SetActive();
+ SetCurrentShader("Mesh");
// Update view-projection matrix
- mMeshShader->SetMatrixUniform("uViewProj", mView * mProjection);
+ pCurrentShader->SetMatrixUniform("uViewProj", mView * mProjection);
// Update lighting uniforms
- SetLightUniforms(mMeshShader);
- for (auto mc : mMeshComps)
+ SetLightUniforms(pCurrentShader);
+ // Loop through each mesh-shader
+ for (auto mclist: mMeshComps)
{
- mc->Draw(mMeshShader);
+ SetCurrentShader(mclist.first);
+ // Loop through each mesh component using the current shader
+ for (MeshComponent* mc: mclist.second)
+ {
+ mc->Draw(pCurrentShader);
+ }
}
-
// Draw all sprite components
// Disable depth buffering
glDisable(GL_DEPTH_TEST);
@@ -144,17 +138,15 @@ void Renderer::Draw()
glEnable(GL_BLEND);
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
-
- // Set shader/vao as active
- mSpriteShader->SetActive();
- mSpriteVerts->SetActive();
- for (auto sprite : mSprites)
+ // Set shader/VAO as active
+ SetCurrentShader("Sprite");
+ pSpriteVerts->SetActive();
+ for (auto sprite: mSprites)
{
- sprite->Draw(mSpriteShader);
+ sprite->Draw(pCurrentShader);
}
-
// Swap the buffers
- SDL_GL_SwapWindow(mWindow);
+ SDL_GL_SwapWindow(pWindow);
}
void Renderer::AddSprite(SpriteComponent* sprite)
@@ -163,16 +155,13 @@ void Renderer::AddSprite(SpriteComponent* sprite)
// (The first element with a higher draw order than me)
int myDrawOrder = sprite->GetDrawOrder();
auto iter = mSprites.begin();
- for (;
- iter != mSprites.end();
- ++iter)
+ for (; iter != mSprites.end(); ++iter)
{
if (myDrawOrder < (*iter)->GetDrawOrder())
{
break;
}
}
-
// Inserts element before position of iterator
mSprites.insert(iter, sprite);
}
@@ -185,13 +174,30 @@ void Renderer::RemoveSprite(SpriteComponent* sprite)
void Renderer::AddMeshComp(MeshComponent* mesh)
{
- mMeshComps.emplace_back(mesh);
+ // Is the shader in the map?
+ auto iter = mMeshComps.find(mesh->GetShaderName());
+ if (iter != mMeshComps.end()) // Yes
+ {
+ // Add the mesh component to the list (vector)
+ iter->second.emplace_back(mesh);
+ }
+ else // No
+ {
+ // Create a new vector containing the mesh component
+ std::vector mcvec = {mesh};
+ // Add the pair to the map
+ mMeshComps.emplace(mesh->GetShaderName(), mcvec);
+ }
}
void Renderer::RemoveMeshComp(MeshComponent* mesh)
{
- auto iter = std::find(mMeshComps.begin(), mMeshComps.end(), mesh);
- mMeshComps.erase(iter);
+ // Retrive the mesh component vector for the specific shader
+ std::vector mcvec = mMeshComps.at(mesh->GetShaderName());
+ // Loop through the vector until you find what you are looking for
+ auto iter = std::find(mcvec.begin(), mcvec.end(), mesh);
+ // remove the mesh componment from the list (vector)
+ mcvec.erase(iter);
}
Texture* Renderer::GetTexture(const std::string& fileName)
@@ -242,33 +248,55 @@ Mesh* Renderer::GetMesh(const std::string & fileName)
return m;
}
+bool Renderer::SetCurrentShader(const std::string& fileName)
+{
+ auto iter = mShaders.find(fileName);
+ if (iter != mShaders.end())
+ {
+ Shader* sh = iter->second;
+ pCurrentShader = sh;
+ sh->SetActive();
+ return true;
+ }
+ return false;
+}
+
+bool Renderer::LoadShader(const std::string& name, const std::string& vertFile, const std::string& fragFile)
+{
+ // Create a new shader
+ Shader* sh = new Shader();
+ if (sh->Load(vertFile, fragFile))
+ {
+ mShaders.emplace(name, sh);
+ pCurrentShader = sh;
+ sh->SetActive();
+ return true;
+ }
+ // Loading failed, so delete the Shader
+ delete sh;
+ sh = nullptr;
+ return false;
+}
+
bool Renderer::LoadShaders()
{
// Create sprite shader
- mSpriteShader = new Shader();
- if (!mSpriteShader->Load("Shaders/Sprite.vert", "Shaders/Sprite.frag"))
+ if(!LoadShader("Sprite", "Shaders/Sprite.vert", "Shaders/Sprite.frag"))
{
return false;
}
-
- mSpriteShader->SetActive();
// Set the view-projection matrix
Matrix4 viewProj = Matrix4::CreateSimpleViewProj(mScreenWidth, mScreenHeight);
- mSpriteShader->SetMatrixUniform("uViewProj", viewProj);
-
+ pCurrentShader->SetMatrixUniform("uViewProj", viewProj);
// Create basic mesh shader
- mMeshShader = new Shader();
- if (!mMeshShader->Load("Shaders/Phong.vert", "Shaders/Phong.frag"))
+ if (!LoadShader("Mesh", "Shaders/Phong.vert", "Shaders/Phong.frag"))
{
return false;
}
-
- mMeshShader->SetActive();
// Set the view-projection matrix
mView = Matrix4::CreateLookAt(Vector3::Zero, Vector3::UnitX, Vector3::UnitZ);
- mProjection = Matrix4::CreatePerspectiveFOV(Math::ToRadians(70.0f),
- mScreenWidth, mScreenHeight, 25.0f, 10000.0f);
- mMeshShader->SetMatrixUniform("uViewProj", mView * mProjection);
+ mProjection = Matrix4::CreatePerspectiveFOV(Math::ToRadians(70.0f), mScreenWidth, mScreenHeight, 25.0f, 10000.0f);
+ pCurrentShader->SetMatrixUniform("uViewProj", mView * mProjection);
return true;
}
@@ -280,13 +308,11 @@ void Renderer::CreateSpriteVerts()
0.5f,-0.5f, 0.f, 0.f, 0.f, 0.0f, 1.f, 1.f, // bottom right
-0.5f,-0.5f, 0.f, 0.f, 0.f, 0.0f, 0.f, 1.f // bottom left
};
-
unsigned int indices[] = {
0, 1, 2,
2, 3, 0
};
-
- mSpriteVerts = new VertexArray(vertices, 4, indices, 6);
+ pSpriteVerts = new VertexArray(vertices, 4, indices, 6);
}
void Renderer::SetLightUniforms(Shader* shader)
@@ -298,10 +324,19 @@ void Renderer::SetLightUniforms(Shader* shader)
// Ambient light
shader->SetVectorUniform("uAmbientLight", mAmbientLight);
// Directional light
- shader->SetVectorUniform("uDirLight.mDirection",
- mDirLight.mDirection);
- shader->SetVectorUniform("uDirLight.mDiffuseColor",
- mDirLight.mDiffuseColor);
- shader->SetVectorUniform("uDirLight.mSpecColor",
- mDirLight.mSpecColor);
-}
+ shader->SetVectorUniform("uDirLight.mDirection", mDirLight.mDirection);
+ shader->SetVectorUniform("uDirLight.mDiffuseColor", mDirLight.mDiffuseColor);
+ shader->SetVectorUniform("uDirLight.mSpecColor", mDirLight.mSpecColor);
+ // Point lights
+ for (int i = 0; i < mPointLights.size(); i++)
+ {
+ std::string intstring = std::to_string(i);
+ shader->SetVectorUniform(((std::string)"uPointLights[" + intstring + "].mWorldPos").c_str(), mPointLights[i].mWorldPos);
+ shader->SetVectorUniform(((std::string)"uPointLights[" + intstring + "].mDiffuseColor").c_str(), mPointLights[i].mDiffuseColor);
+ shader->SetVectorUniform(((std::string)"uPointLights[" + intstring + "].mSpecColor").c_str(), mPointLights[i].mSpecColor);
+ shader->SetFloatUniform(((std::string)"uPointLights[" + intstring + "].mInnerRadius").c_str(), mPointLights[i].mInnerRadius);
+ shader->SetFloatUniform(((std::string)"uPointLights[" + intstring + "].mOuterRadius").c_str(), mPointLights[i].mOuterRadius);
+ }
+ // Pass the size of the array to the shader
+ shader->SetIntUniform("uNumPointLights", mPointLights.size());
+}
\ No newline at end of file
diff --git a/Chapter06/Renderer.h b/Chapter06/Renderer.h
index 12746df2..e74ee2fd 100644
--- a/Chapter06/Renderer.h
+++ b/Chapter06/Renderer.h
@@ -23,74 +23,76 @@ struct DirectionalLight
Vector3 mSpecColor;
};
+struct PointLight
+{
+ // Position of light
+ Vector3 mWorldPos;
+ // Diffuse color
+ Vector3 mDiffuseColor;
+ // Specular color
+ Vector3 mSpecColor;
+ // Radius of the light
+ float mInnerRadius;
+ float mOuterRadius;
+};
+
class Renderer
{
public:
Renderer(class Game* game);
~Renderer();
-
bool Initialize(float screenWidth, float screenHeight);
void Shutdown();
void UnloadData();
-
void Draw();
-
void AddSprite(class SpriteComponent* sprite);
void RemoveSprite(class SpriteComponent* sprite);
-
void AddMeshComp(class MeshComponent* mesh);
void RemoveMeshComp(class MeshComponent* mesh);
-
class Texture* GetTexture(const std::string& fileName);
class Mesh* GetMesh(const std::string& fileName);
-
+ bool SetCurrentShader(const std::string& fileName);
void SetViewMatrix(const Matrix4& view) { mView = view; }
-
void SetAmbientLight(const Vector3& ambient) { mAmbientLight = ambient; }
DirectionalLight& GetDirectionalLight() { return mDirLight; }
-
+ std::vector* GetPointLights() { return &mPointLights; }
float GetScreenWidth() const { return mScreenWidth; }
float GetScreenHeight() const { return mScreenHeight; }
private:
+ // Creates a new shader and sets it as the current shader
+ bool LoadShader(const std::string& name, const std::string& vertFile, const std::string& fragFile);
+ // Loads all shaders
bool LoadShaders();
void CreateSpriteVerts();
void SetLightUniforms(class Shader* shader);
-
// Map of textures loaded
std::unordered_map mTextures;
// Map of meshes loaded
std::unordered_map mMeshes;
-
+ // Map of shaders loaded
+ std::unordered_map mShaders;
+ // Map linking mesh components to specific shaders
+ std::unordered_map> mMeshComps;
// All the sprite components drawn
std::vector mSprites;
-
- // All mesh components drawn
- std::vector mMeshComps;
-
// Game
- class Game* mGame;
-
- // Sprite shader
- class Shader* mSpriteShader;
+ class Game* pGame;
+ // Current shader
+ class Shader* pCurrentShader;
// Sprite vertex array
- class VertexArray* mSpriteVerts;
-
- // Mesh shader
- class Shader* mMeshShader;
-
+ class VertexArray* pSpriteVerts;
// View/projection for 3D shaders
Matrix4 mView;
Matrix4 mProjection;
// Width/height of screen
float mScreenWidth;
float mScreenHeight;
-
// Lighting data
Vector3 mAmbientLight;
DirectionalLight mDirLight;
-
+ std::vector mPointLights = {};
// Window
- SDL_Window* mWindow;
+ SDL_Window* pWindow;
// OpenGL context
SDL_GLContext mContext;
};
\ No newline at end of file
diff --git a/Chapter06/Shader.cpp b/Chapter06/Shader.cpp
index cae3ac07..3ca5f725 100644
--- a/Chapter06/Shader.cpp
+++ b/Chapter06/Shader.cpp
@@ -12,45 +12,32 @@
#include
#include
-Shader::Shader()
- : mShaderProgram(0)
- , mVertexShader(0)
- , mFragShader(0)
+Shader::Shader(): mShaderProgram(0), mVertexShader(0), mFragShader(0)
{
-
}
Shader::~Shader()
{
-
}
bool Shader::Load(const std::string& vertName, const std::string& fragName)
{
// Compile vertex and pixel shaders
- if (!CompileShader(vertName,
- GL_VERTEX_SHADER,
- mVertexShader) ||
- !CompileShader(fragName,
- GL_FRAGMENT_SHADER,
- mFragShader))
+ if (!CompileShader(vertName, GL_VERTEX_SHADER, mVertexShader) || !CompileShader(fragName, GL_FRAGMENT_SHADER, mFragShader))
{
return false;
}
-
// Now create a shader program that
// links together the vertex/frag shaders
mShaderProgram = glCreateProgram();
glAttachShader(mShaderProgram, mVertexShader);
glAttachShader(mShaderProgram, mFragShader);
glLinkProgram(mShaderProgram);
-
// Verify that the program linked successfully
if (!IsValidProgram())
{
return false;
}
-
return true;
}
@@ -90,9 +77,14 @@ void Shader::SetFloatUniform(const char* name, float value)
glUniform1f(loc, value);
}
-bool Shader::CompileShader(const std::string& fileName,
- GLenum shaderType,
- GLuint& outShader)
+void Shader::SetIntUniform(const char* name, int value)
+{
+ GLuint loc = glGetUniformLocation(mShaderProgram, name);
+ // Send the float data
+ glUniform1i(loc, value);
+}
+
+bool Shader::CompileShader(const std::string& fileName, GLenum shaderType, GLuint& outShader)
{
// Open file
std::ifstream shaderFile(fileName);
@@ -103,13 +95,11 @@ bool Shader::CompileShader(const std::string& fileName,
sstream << shaderFile.rdbuf();
std::string contents = sstream.str();
const char* contentsChar = contents.c_str();
-
// Create a shader of the specified type
outShader = glCreateShader(shaderType);
// Set the source characters and try to compile
glShaderSource(outShader, 1, &(contentsChar), nullptr);
glCompileShader(outShader);
-
if (!IsCompiled(outShader))
{
SDL_Log("Failed to compile shader %s", fileName.c_str());
@@ -121,7 +111,6 @@ bool Shader::CompileShader(const std::string& fileName,
SDL_Log("Shader file not found: %s", fileName.c_str());
return false;
}
-
return true;
}
@@ -130,7 +119,6 @@ bool Shader::IsCompiled(GLuint shader)
GLint status;
// Query the compile status
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
-
if (status != GL_TRUE)
{
char buffer[512];
@@ -139,13 +127,11 @@ bool Shader::IsCompiled(GLuint shader)
SDL_Log("GLSL Compile Failed:\n%s", buffer);
return false;
}
-
return true;
}
bool Shader::IsValidProgram()
{
-
GLint status;
// Query the link status
glGetProgramiv(mShaderProgram, GL_LINK_STATUS, &status);
@@ -157,6 +143,5 @@ bool Shader::IsValidProgram()
SDL_Log("GLSL Link Status:\n%s", buffer);
return false;
}
-
return true;
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Shader.h b/Chapter06/Shader.h
index 929c9e41..78bb8533 100644
--- a/Chapter06/Shader.h
+++ b/Chapter06/Shader.h
@@ -27,12 +27,11 @@ class Shader
void SetVectorUniform(const char* name, const Vector3& vector);
// Sets a float uniform
void SetFloatUniform(const char* name, float value);
+ // Sets a int uniform
+ void SetIntUniform(const char* name, int value);
private:
// Tries to compile the specified shader
- bool CompileShader(const std::string& fileName,
- GLenum shaderType,
- GLuint& outShader);
-
+ bool CompileShader(const std::string& fileName, GLenum shaderType, GLuint& outShader);
// Tests whether shader compiled successfully
bool IsCompiled(GLuint shader);
// Tests whether vertex/fragment programs link
@@ -42,4 +41,4 @@ class Shader
GLuint mVertexShader;
GLuint mFragShader;
GLuint mShaderProgram;
-};
+};
\ No newline at end of file
diff --git a/Chapter06/Shaders/BasicMesh.frag b/Chapter06/Shaders/BasicMesh.frag
index 481a669a..54f0924f 100644
--- a/Chapter06/Shaders/BasicMesh.frag
+++ b/Chapter06/Shaders/BasicMesh.frag
@@ -11,10 +11,8 @@
// Tex coord input from vertex shader
in vec2 fragTexCoord;
-
// This corresponds to the output color to the color buffer
out vec4 outColor;
-
// This is used for the texture sampling
uniform sampler2D uTexture;
@@ -22,4 +20,4 @@ void main()
{
// Sample color from texture
outColor = texture(uTexture, fragTexCoord);
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Shaders/BasicMesh.vert b/Chapter06/Shaders/BasicMesh.vert
index 7d21ad0d..297d197b 100644
--- a/Chapter06/Shaders/BasicMesh.vert
+++ b/Chapter06/Shaders/BasicMesh.vert
@@ -12,12 +12,10 @@
// Uniforms for world transform and view-proj
uniform mat4 uWorldTransform;
uniform mat4 uViewProj;
-
// Attribute 0 is position, 1 is normal, 2 is tex coords.
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inTexCoord;
-
// Any vertex outputs (other than position)
out vec2 fragTexCoord;
@@ -27,7 +25,6 @@ void main()
vec4 pos = vec4(inPosition, 1.0);
// Transform to position world space, then clip space
gl_Position = pos * uWorldTransform * uViewProj;
-
// Pass along the texture coordinate to frag shader
fragTexCoord = inTexCoord;
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Shaders/Phong.frag b/Chapter06/Shaders/Phong.frag
index 7bb2678c..0da5eb6c 100644
--- a/Chapter06/Shaders/Phong.frag
+++ b/Chapter06/Shaders/Phong.frag
@@ -16,13 +16,10 @@ in vec2 fragTexCoord;
in vec3 fragNormal;
// Position (in world space)
in vec3 fragWorldPos;
-
// This corresponds to the output color to the color buffer
out vec4 outColor;
-
// This is used for the texture sampling
uniform sampler2D uTexture;
-
// Create a struct for directional light
struct DirectionalLight
{
@@ -33,7 +30,19 @@ struct DirectionalLight
// Specular color
vec3 mSpecColor;
};
-
+// Create a struct for point light
+struct PointLight
+{
+ // Position of light
+ vec3 mWorldPos;
+ // Diffuse color
+ vec3 mDiffuseColor;
+ // Specular color
+ vec3 mSpecColor;
+ // Radius of the light
+ float mInnerRadius;
+ float mOuterRadius;
+};
// Uniforms for lighting
// Camera position (in world space)
uniform vec3 uCameraPos;
@@ -41,31 +50,57 @@ uniform vec3 uCameraPos;
uniform float uSpecPower;
// Ambient light level
uniform vec3 uAmbientLight;
-
// Directional Light
uniform DirectionalLight uDirLight;
+// Point Lights
+uniform PointLight[4] uPointLights;
+// Size of PointLight array
+uniform int uNumPointLights;
void main()
{
+ vec4 output = texture(uTexture, fragTexCoord);
// Surface normal
vec3 N = normalize(fragNormal);
- // Vector from surface to light
- vec3 L = normalize(-uDirLight.mDirection);
// Vector from surface to camera
vec3 V = normalize(uCameraPos - fragWorldPos);
+// Directional Light:
+ // Vector from surface to light
+ vec3 D_L = normalize(-uDirLight.mDirection);
// Reflection of -L about N
- vec3 R = normalize(reflect(-L, N));
-
+ vec3 D_R = normalize(reflect(-D_L, N));
// Compute phong reflection
- vec3 Phong = uAmbientLight;
- float NdotL = dot(N, L);
- if (NdotL > 0)
+ vec3 D_Phong = uAmbientLight;
+ float D_NdotL = dot(N, D_L);
+ if (D_NdotL > 0)
{
- vec3 Diffuse = uDirLight.mDiffuseColor * NdotL;
- vec3 Specular = uDirLight.mSpecColor * pow(max(0.0, dot(R, V)), uSpecPower);
- Phong += Diffuse + Specular;
+ vec3 D_Diffuse = uDirLight.mDiffuseColor * D_NdotL;
+ vec3 D_Specular = uDirLight.mSpecColor * pow(max(0.0, dot(D_R, V)), uSpecPower);
+ D_Phong += D_Diffuse + D_Specular;
+ }
+ output *= vec4(D_Phong, 1.0f);
+// Point Lights:
+ for(int i = 0; i < uNumPointLights; i++)
+ {
+ // Vector from surface to light
+ vec3 P_L = normalize(uPointLights[i].mWorldPos - fragWorldPos);
+ // Reflection of -L about N
+ vec3 P_R = normalize(reflect(-P_L, N));
+ // Compute phong reflection
+ vec3 P_Phong = vec3(1.0f, 1.0f, 1.0f);
+ float P_NdotL = dot(N, P_L);
+ if (P_NdotL > 0)
+ {
+ // Get the distance between the light and the world pos
+ float dist = distance(uPointLights[i].mWorldPos, fragWorldPos);
+ // Use smoothstep to compute value in range [0,1] between inner/outer radius
+ float intensity = smoothstep(uPointLights[i].mInnerRadius, uPointLights[i].mOuterRadius, dist);
+ vec3 P_Diffuse = mix(uPointLights[i].mDiffuseColor, vec3(0.0, 0.0, 0.0), intensity) * P_NdotL;
+ vec3 P_Specular = mix(uPointLights[i].mSpecColor, vec3(0.0, 0.0, 0.0), intensity) * pow(max(0.0, dot(P_R, V)), uSpecPower);
+ P_Phong += P_Diffuse + P_Specular;
+ output *= vec4(P_Phong, 1.0f);
+ }
}
-
// Final color is texture color times phong light (alpha = 1)
- outColor = texture(uTexture, fragTexCoord) * vec4(Phong, 1.0f);
-}
+ outColor = output;
+}
\ No newline at end of file
diff --git a/Chapter06/Shaders/Phong.vert b/Chapter06/Shaders/Phong.vert
index af5078dc..cfa49a2b 100644
--- a/Chapter06/Shaders/Phong.vert
+++ b/Chapter06/Shaders/Phong.vert
@@ -12,12 +12,10 @@
// Uniforms for world transform and view-proj
uniform mat4 uWorldTransform;
uniform mat4 uViewProj;
-
// Attribute 0 is position, 1 is normal, 2 is tex coords.
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inTexCoord;
-
// Any vertex outputs (other than position)
out vec2 fragTexCoord;
// Normal (in world space)
@@ -35,10 +33,8 @@ void main()
fragWorldPos = pos.xyz;
// Transform to clip space
gl_Position = pos * uViewProj;
-
// Transform normal into world space (w = 0)
fragNormal = (vec4(inNormal, 0.0f) * uWorldTransform).xyz;
-
// Pass along the texture coordinate to frag shader
fragTexCoord = inTexCoord;
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Shaders/Sprite.frag b/Chapter06/Shaders/Sprite.frag
index 481a669a..54f0924f 100644
--- a/Chapter06/Shaders/Sprite.frag
+++ b/Chapter06/Shaders/Sprite.frag
@@ -11,10 +11,8 @@
// Tex coord input from vertex shader
in vec2 fragTexCoord;
-
// This corresponds to the output color to the color buffer
out vec4 outColor;
-
// This is used for the texture sampling
uniform sampler2D uTexture;
@@ -22,4 +20,4 @@ void main()
{
// Sample color from texture
outColor = texture(uTexture, fragTexCoord);
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Shaders/Sprite.vert b/Chapter06/Shaders/Sprite.vert
index 7d21ad0d..297d197b 100644
--- a/Chapter06/Shaders/Sprite.vert
+++ b/Chapter06/Shaders/Sprite.vert
@@ -12,12 +12,10 @@
// Uniforms for world transform and view-proj
uniform mat4 uWorldTransform;
uniform mat4 uViewProj;
-
// Attribute 0 is position, 1 is normal, 2 is tex coords.
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inTexCoord;
-
// Any vertex outputs (other than position)
out vec2 fragTexCoord;
@@ -27,7 +25,6 @@ void main()
vec4 pos = vec4(inPosition, 1.0);
// Transform to position world space, then clip space
gl_Position = pos * uWorldTransform * uViewProj;
-
// Pass along the texture coordinate to frag shader
fragTexCoord = inTexCoord;
-}
+}
\ No newline at end of file
diff --git a/Chapter06/SpriteComponent.cpp b/Chapter06/SpriteComponent.cpp
index eb7b77aa..f81296db 100644
--- a/Chapter06/SpriteComponent.cpp
+++ b/Chapter06/SpriteComponent.cpp
@@ -13,40 +13,29 @@
#include "Game.h"
#include "Renderer.h"
-SpriteComponent::SpriteComponent(Actor* owner, int drawOrder)
- :Component(owner)
- ,mTexture(nullptr)
- ,mDrawOrder(drawOrder)
- ,mTexWidth(0)
- ,mTexHeight(0)
+SpriteComponent::SpriteComponent(Actor* owner, int drawOrder): Component(owner), pTexture(nullptr), mDrawOrder(drawOrder), mTexWidth(0), mTexHeight(0)
{
- mOwner->GetGame()->GetRenderer()->AddSprite(this);
+ pOwner->GetGame()->GetRenderer()->AddSprite(this);
}
SpriteComponent::~SpriteComponent()
{
- mOwner->GetGame()->GetRenderer()->RemoveSprite(this);
+ pOwner->GetGame()->GetRenderer()->RemoveSprite(this);
}
void SpriteComponent::Draw(Shader* shader)
{
- if (mTexture)
+ if (pTexture)
{
// Scale the quad by the width/height of texture
- Matrix4 scaleMat = Matrix4::CreateScale(
- static_cast(mTexWidth),
- static_cast(mTexHeight),
- 1.0f);
-
- Matrix4 world = scaleMat * mOwner->GetWorldTransform();
-
+ Matrix4 scaleMat = Matrix4::CreateScale(static_cast(mTexWidth), static_cast(mTexHeight), 1.0f);
+ Matrix4 world = scaleMat * pOwner->GetWorldTransform();
// Since all sprites use the same shader/vertices,
// the game first sets them active before any sprite draws
-
// Set world transform
shader->SetMatrixUniform("uWorldTransform", world);
// Set current texture
- mTexture->SetActive();
+ pTexture->SetActive();
// Draw quad
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
}
@@ -54,8 +43,8 @@ void SpriteComponent::Draw(Shader* shader)
void SpriteComponent::SetTexture(Texture* texture)
{
- mTexture = texture;
+ pTexture = texture;
// Set width/height
mTexWidth = texture->GetWidth();
mTexHeight = texture->GetHeight();
-}
+}
\ No newline at end of file
diff --git a/Chapter06/SpriteComponent.h b/Chapter06/SpriteComponent.h
index 6c5642f2..581cb883 100644
--- a/Chapter06/SpriteComponent.h
+++ b/Chapter06/SpriteComponent.h
@@ -9,22 +9,20 @@
#pragma once
#include "Component.h"
#include "SDL/SDL.h"
-class SpriteComponent : public Component
+class SpriteComponent: public Component
{
public:
// (Lower draw order corresponds with further back)
SpriteComponent(class Actor* owner, int drawOrder = 100);
~SpriteComponent();
-
virtual void Draw(class Shader* shader);
virtual void SetTexture(class Texture* texture);
-
int GetDrawOrder() const { return mDrawOrder; }
int GetTexHeight() const { return mTexHeight; }
int GetTexWidth() const { return mTexWidth; }
protected:
- class Texture* mTexture;
+ class Texture* pTexture;
int mDrawOrder;
int mTexWidth;
int mTexHeight;
-};
+};
\ No newline at end of file
diff --git a/Chapter06/Texture.cpp b/Chapter06/Texture.cpp
index ddde35f0..a2c632c9 100644
--- a/Chapter06/Texture.cpp
+++ b/Chapter06/Texture.cpp
@@ -11,50 +11,35 @@
#include
#include
-Texture::Texture()
-:mTextureID(0)
-,mWidth(0)
-,mHeight(0)
+Texture::Texture(): mTextureID(0), mWidth(0), mHeight(0)
{
-
}
Texture::~Texture()
{
-
}
bool Texture::Load(const std::string& fileName)
{
int channels = 0;
-
- unsigned char* image = SOIL_load_image(fileName.c_str(),
- &mWidth, &mHeight, &channels, SOIL_LOAD_AUTO);
-
+ unsigned char* image = SOIL_load_image(fileName.c_str(), &mWidth, &mHeight, &channels, SOIL_LOAD_AUTO);
if (image == nullptr)
{
SDL_Log("SOIL failed to load image %s: %s", fileName.c_str(), SOIL_last_result());
return false;
}
-
int format = GL_RGB;
if (channels == 4)
{
format = GL_RGBA;
}
-
glGenTextures(1, &mTextureID);
glBindTexture(GL_TEXTURE_2D, mTextureID);
-
- glTexImage2D(GL_TEXTURE_2D, 0, format, mWidth, mHeight, 0, format,
- GL_UNSIGNED_BYTE, image);
-
+ glTexImage2D(GL_TEXTURE_2D, 0, format, mWidth, mHeight, 0, format, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
-
// Enable linear filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
return true;
}
@@ -66,4 +51,4 @@ void Texture::Unload()
void Texture::SetActive()
{
glBindTexture(GL_TEXTURE_2D, mTextureID);
-}
+}
\ No newline at end of file
diff --git a/Chapter06/Texture.h b/Chapter06/Texture.h
index 6c8892fd..b2059450 100644
--- a/Chapter06/Texture.h
+++ b/Chapter06/Texture.h
@@ -13,16 +13,13 @@ class Texture
public:
Texture();
~Texture();
-
bool Load(const std::string& fileName);
void Unload();
-
void SetActive();
-
int GetWidth() const { return mWidth; }
int GetHeight() const { return mHeight; }
private:
unsigned int mTextureID;
int mWidth;
int mHeight;
-};
+};
\ No newline at end of file
diff --git a/Chapter06/VertexArray.cpp b/Chapter06/VertexArray.cpp
index faddcf6c..e97c3bdd 100644
--- a/Chapter06/VertexArray.cpp
+++ b/Chapter06/VertexArray.cpp
@@ -9,25 +9,19 @@
#include "VertexArray.h"
#include
-VertexArray::VertexArray(const float* verts, unsigned int numVerts,
- const unsigned int* indices, unsigned int numIndices)
- :mNumVerts(numVerts)
- ,mNumIndices(numIndices)
+VertexArray::VertexArray(const float* verts, unsigned int numVerts, const unsigned int* indices, unsigned int numIndices): mNumVerts(numVerts), mNumIndices(numIndices)
{
// Create vertex array
glGenVertexArrays(1, &mVertexArray);
glBindVertexArray(mVertexArray);
-
// Create vertex buffer
glGenBuffers(1, &mVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, numVerts * 8 * sizeof(float), verts, GL_STATIC_DRAW);
-
// Create index buffer
glGenBuffers(1, &mIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(unsigned int), indices, GL_STATIC_DRAW);
-
// Specify the vertex attributes
// (For now, assume one vertex format)
// Position is 3 floats
@@ -35,12 +29,10 @@ VertexArray::VertexArray(const float* verts, unsigned int numVerts,
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), 0);
// Normal is 3 floats
glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float),
- reinterpret_cast(sizeof(float) * 3));
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), reinterpret_cast(sizeof(float) * 3));
// Texture coordinates is 2 floats
glEnableVertexAttribArray(2);
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float),
- reinterpret_cast(sizeof(float) * 6));
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), reinterpret_cast(sizeof(float) * 6));
}
VertexArray::~VertexArray()
@@ -53,4 +45,4 @@ VertexArray::~VertexArray()
void VertexArray::SetActive()
{
glBindVertexArray(mVertexArray);
-}
+}
\ No newline at end of file
diff --git a/Chapter06/VertexArray.h b/Chapter06/VertexArray.h
index 5deddc4d..480a254b 100644
--- a/Chapter06/VertexArray.h
+++ b/Chapter06/VertexArray.h
@@ -10,10 +10,8 @@
class VertexArray
{
public:
- VertexArray(const float* verts, unsigned int numVerts,
- const unsigned int* indices, unsigned int numIndices);
+ VertexArray(const float* verts, unsigned int numVerts, const unsigned int* indices, unsigned int numIndices);
~VertexArray();
-
void SetActive();
unsigned int GetNumIndices() const { return mNumIndices; }
unsigned int GetNumVerts() const { return mNumVerts; }
diff --git a/Chapter07/Actor.cpp b/Chapter07/Actor.cpp
index b3715cca..50680410 100644
--- a/Chapter07/Actor.cpp
+++ b/Chapter07/Actor.cpp
@@ -11,20 +11,14 @@
#include "Component.h"
#include
-Actor::Actor(Game* game)
- :mState(EActive)
- ,mPosition(Vector3::Zero)
- ,mRotation(Quaternion::Identity)
- ,mScale(1.0f)
- ,mGame(game)
- ,mRecomputeWorldTransform(true)
+Actor::Actor(Game* game): mState(EActive), mPosition(Vector3::Zero), mOldPosition(Vector3::Zero), mVelocity(Vector3::Zero), mRotation(Quaternion::Identity), mScale(1.0f), pGame(game), mRecomputeWorldTransform(true)
{
- mGame->AddActor(this);
+ pGame->AddActor(this);
}
Actor::~Actor()
{
- mGame->RemoveActor(this);
+ pGame->RemoveActor(this);
// Need to delete components
// Because ~Component calls RemoveComponent, need a different style loop
while (!mComponents.empty())
@@ -38,17 +32,15 @@ void Actor::Update(float deltaTime)
if (mState == EActive)
{
ComputeWorldTransform();
-
UpdateComponents(deltaTime);
UpdateActor(deltaTime);
-
ComputeWorldTransform();
}
}
void Actor::UpdateComponents(float deltaTime)
{
- for (auto comp : mComponents)
+ for (auto comp: mComponents)
{
comp->Update(deltaTime);
}
@@ -56,6 +48,14 @@ void Actor::UpdateComponents(float deltaTime)
void Actor::UpdateActor(float deltaTime)
{
+ if (mPosition != mOldPosition)
+ {
+ // NOTE: Velocity is change in position/time
+ mVelocity.x = (mPosition - mOldPosition).x / deltaTime;
+ mVelocity.y = (mPosition - mOldPosition).y / deltaTime;
+ mVelocity.z = (mPosition - mOldPosition).z / deltaTime;
+ mOldPosition = mPosition;
+ }
}
void Actor::ProcessInput(const uint8_t* keyState)
@@ -63,11 +63,10 @@ void Actor::ProcessInput(const uint8_t* keyState)
if (mState == EActive)
{
// First process input for components
- for (auto comp : mComponents)
+ for (auto comp: mComponents)
{
comp->ProcessInput(keyState);
}
-
ActorInput(keyState);
}
}
@@ -85,9 +84,8 @@ void Actor::ComputeWorldTransform()
mWorldTransform = Matrix4::CreateScale(mScale);
mWorldTransform *= Matrix4::CreateFromQuaternion(mRotation);
mWorldTransform *= Matrix4::CreateTranslation(mPosition);
-
// Inform components world transform updated
- for (auto comp : mComponents)
+ for (auto comp: mComponents)
{
comp->OnUpdateWorldTransform();
}
@@ -96,20 +94,16 @@ void Actor::ComputeWorldTransform()
void Actor::AddComponent(Component* component)
{
- // Find the insertion point in the sorted vector
- // (The first element with a order higher than me)
+ // Find the insertion point in the sorted vector (The first element with a order higher than me)
int myOrder = component->GetUpdateOrder();
auto iter = mComponents.begin();
- for (;
- iter != mComponents.end();
- ++iter)
+ for (; iter != mComponents.end(); ++iter)
{
if (myOrder < (*iter)->GetUpdateOrder())
{
break;
}
}
-
// Inserts element before position of iterator
mComponents.insert(iter, component);
}
@@ -121,4 +115,4 @@ void Actor::RemoveComponent(Component* component)
{
mComponents.erase(iter);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Actor.h b/Chapter07/Actor.h
index 05d6b1b6..953b70aa 100644
--- a/Chapter07/Actor.h
+++ b/Chapter07/Actor.h
@@ -20,22 +20,18 @@ class Actor
EPaused,
EDead
};
-
Actor(class Game* game);
virtual ~Actor();
-
// Update function called from Game (not overridable)
void Update(float deltaTime);
// Updates all the components attached to the actor (not overridable)
void UpdateComponents(float deltaTime);
// Any actor-specific update code (overridable)
virtual void UpdateActor(float deltaTime);
-
// ProcessInput function called from Game (not overridable)
void ProcessInput(const uint8_t* keyState);
// Any actor-specific input code (overridable)
virtual void ActorInput(const uint8_t* keyState);
-
// Getters/setters
const Vector3& GetPosition() const { return mPosition; }
void SetPosition(const Vector3& pos) { mPosition = pos; mRecomputeWorldTransform = true; }
@@ -43,32 +39,27 @@ class Actor
void SetScale(float scale) { mScale = scale; mRecomputeWorldTransform = true; }
const Quaternion& GetRotation() const { return mRotation; }
void SetRotation(const Quaternion& rotation) { mRotation = rotation; mRecomputeWorldTransform = true; }
-
void ComputeWorldTransform();
const Matrix4& GetWorldTransform() const { return mWorldTransform; }
-
Vector3 GetForward() const { return Vector3::Transform(Vector3::UnitX, mRotation); }
-
+ Vector3 GetVelocity() const { return mVelocity; }
State GetState() const { return mState; }
void SetState(State state) { mState = state; }
-
- class Game* GetGame() { return mGame; }
-
-
+ class Game* GetGame() { return pGame; }
// Add/remove components
void AddComponent(class Component* component);
void RemoveComponent(class Component* component);
private:
// Actor's state
State mState;
-
// Transform
Matrix4 mWorldTransform;
Vector3 mPosition;
+ Vector3 mOldPosition;
+ Vector3 mVelocity;
Quaternion mRotation;
float mScale;
bool mRecomputeWorldTransform;
-
std::vector mComponents;
- class Game* mGame;
-};
+ class Game* pGame;
+};
\ No newline at end of file
diff --git a/Chapter07/AudioComponent.cpp b/Chapter07/AudioComponent.cpp
index 3131b08b..eab56550 100644
--- a/Chapter07/AudioComponent.cpp
+++ b/Chapter07/AudioComponent.cpp
@@ -11,8 +11,7 @@
#include "Game.h"
#include "AudioSystem.h"
-AudioComponent::AudioComponent(Actor* owner, int updateOrder)
- :Component(owner, updateOrder)
+AudioComponent::AudioComponent(Actor* owner, int updateOrder): Component(owner, updateOrder)
{
}
@@ -24,7 +23,6 @@ AudioComponent::~AudioComponent()
void AudioComponent::Update(float deltaTime)
{
Component::Update(deltaTime);
-
// Remove invalid 2D events
auto iter = mEvents2D.begin();
while (iter != mEvents2D.end())
@@ -38,7 +36,6 @@ void AudioComponent::Update(float deltaTime)
++iter;
}
}
-
// Remove invalid 3D events
iter = mEvents3D.begin();
while (iter != mEvents3D.end())
@@ -57,25 +54,24 @@ void AudioComponent::Update(float deltaTime)
void AudioComponent::OnUpdateWorldTransform()
{
// Update 3D events' world transforms
- Matrix4 world = mOwner->GetWorldTransform();
- for (auto& event : mEvents3D)
+ for (auto& event: mEvents3D)
{
if (event.IsValid())
{
- event.Set3DAttributes(world);
+ event.Set3DAttributes(pOwner->GetWorldTransform(), pOwner->GetVelocity());
}
}
}
SoundEvent AudioComponent::PlayEvent(const std::string& name)
{
- SoundEvent e = mOwner->GetGame()->GetAudioSystem()->PlayEvent(name);
+ SoundEvent e = pOwner->GetGame()->GetAudioSystem()->PlayEvent(name);
// Is this 2D or 3D?
if (e.Is3D())
{
mEvents3D.emplace_back(e);
// Set initial 3D attributes
- e.Set3DAttributes(mOwner->GetWorldTransform());
+ e.Set3DAttributes(pOwner->GetWorldTransform(), pOwner->GetVelocity());
}
else
{
@@ -87,15 +83,15 @@ SoundEvent AudioComponent::PlayEvent(const std::string& name)
void AudioComponent::StopAllEvents()
{
// Stop all sounds
- for (auto& e : mEvents2D)
+ for (auto& e: mEvents2D)
{
e.Stop();
}
- for (auto& e : mEvents3D)
+ for (auto& e: mEvents3D)
{
e.Stop();
}
// Clear events
mEvents2D.clear();
mEvents3D.clear();
-}
+}
\ No newline at end of file
diff --git a/Chapter07/AudioComponent.h b/Chapter07/AudioComponent.h
index 8fdecd2d..76bbe2da 100644
--- a/Chapter07/AudioComponent.h
+++ b/Chapter07/AudioComponent.h
@@ -17,10 +17,8 @@ class AudioComponent : public Component
public:
AudioComponent(class Actor* owner, int updateOrder = 200);
~AudioComponent();
-
void Update(float deltaTime) override;
void OnUpdateWorldTransform() override;
-
SoundEvent PlayEvent(const std::string& name);
void StopAllEvents();
private:
diff --git a/Chapter07/AudioSystem.cpp b/Chapter07/AudioSystem.cpp
index 73c5feff..6ae30de7 100644
--- a/Chapter07/AudioSystem.cpp
+++ b/Chapter07/AudioSystem.cpp
@@ -14,10 +14,7 @@
unsigned int AudioSystem::sNextID = 0;
-AudioSystem::AudioSystem(Game* game)
- :mGame(game)
- ,mSystem(nullptr)
- ,mLowLevelSystem(nullptr)
+AudioSystem::AudioSystem(Game* game): pGame(game), pSystem(nullptr)
{
}
@@ -32,18 +29,16 @@ bool AudioSystem::Initialize()
FMOD_DEBUG_LEVEL_ERROR, // Log only errors
FMOD_DEBUG_MODE_TTY // Output to stdout
);
-
// Create FMOD studio system object
FMOD_RESULT result;
- result = FMOD::Studio::System::create(&mSystem);
+ result = FMOD::Studio::System::create(&pSystem);
if (result != FMOD_OK)
{
SDL_Log("Failed to create FMOD system: %s", FMOD_ErrorString(result));
return false;
}
-
// Initialize FMOD studio system
- result = mSystem->initialize(
+ result = pSystem->initialize(
512, // Max number of concurrent sounds
FMOD_STUDIO_INIT_NORMAL, // Use default settings
FMOD_INIT_NORMAL, // Use default settings
@@ -54,14 +49,11 @@ bool AudioSystem::Initialize()
SDL_Log("Failed to initialize FMOD system: %s", FMOD_ErrorString(result));
return false;
}
-
- // Save the low-level system pointer
- mSystem->getLowLevelSystem(&mLowLevelSystem);
-
+ // Save the core system pointer
+ pSystem->getCoreSystem(&pCoreSystem);
// Load the master banks (strings first)
LoadBank("Assets/Master Bank.strings.bank");
LoadBank("Assets/Master Bank.bank");
-
return true;
}
@@ -70,9 +62,9 @@ void AudioSystem::Shutdown()
// Unload all banks
UnloadAllBanks();
// Shutdown FMOD system
- if (mSystem)
+ if (pSystem)
{
- mSystem->release();
+ pSystem->release();
}
}
@@ -83,15 +75,13 @@ void AudioSystem::LoadBank(const std::string& name)
{
return;
}
-
// Try to load bank
FMOD::Studio::Bank* bank = nullptr;
- FMOD_RESULT result = mSystem->loadBankFile(
+ FMOD_RESULT result = pSystem->loadBankFile(
name.c_str(), // File name of bank
FMOD_STUDIO_LOAD_BANK_NORMAL, // Normal loading
&bank // Save pointer to bank
);
-
const int maxPathLength = 512;
if (result == FMOD_OK)
{
@@ -146,7 +136,6 @@ void AudioSystem::UnloadBank(const std::string& name)
{
return;
}
-
// First we need to remove all events from this bank
FMOD::Studio::Bank* bank = iter->second;
int numEvents = 0;
@@ -193,7 +182,6 @@ void AudioSystem::UnloadBank(const std::string& name)
}
}
}
-
// Unload sample data and bank
bank->unloadSampleData();
bank->unload();
@@ -253,15 +241,13 @@ void AudioSystem::Update(float deltaTime)
done.emplace_back(iter.first);
}
}
-
// Remove done event instances from map
for (auto id : done)
{
mEventInstances.erase(id);
}
-
// Update FMOD
- mSystem->update();
+ pSystem->update();
}
namespace
@@ -278,7 +264,7 @@ namespace
}
}
-void AudioSystem::SetListener(const Matrix4& viewMatrix)
+void AudioSystem::SetListener(const Matrix4& viewMatrix, const Vector3& velocity)
{
// Invert the view matrix to get the correct vectors
Matrix4 invView = viewMatrix;
@@ -290,10 +276,10 @@ void AudioSystem::SetListener(const Matrix4& viewMatrix)
listener.forward = VecToFMOD(invView.GetZAxis());
// In the inverted view, second row is up
listener.up = VecToFMOD(invView.GetYAxis());
- // Set velocity to zero (fix if using Doppler effect)
- listener.velocity = {0.0f, 0.0f, 0.0f};
+ // Set velocity
+ listener.velocity = VecToFMOD(velocity);
// Send to FMOD
- mSystem->setListenerAttributes(0, &listener);
+ pSystem->setListenerAttributes(0, &listener);
}
float AudioSystem::GetBusVolume(const std::string& name) const
@@ -345,4 +331,4 @@ FMOD::Studio::EventInstance* AudioSystem::GetEventInstance(unsigned int id)
event = iter->second;
}
return event;
-}
+}
\ No newline at end of file
diff --git a/Chapter07/AudioSystem.h b/Chapter07/AudioSystem.h
index 1e7398ef..2ff757a7 100644
--- a/Chapter07/AudioSystem.h
+++ b/Chapter07/AudioSystem.h
@@ -31,21 +31,16 @@ class AudioSystem
public:
AudioSystem(class Game* game);
~AudioSystem();
-
bool Initialize();
void Shutdown();
-
// Load/unload banks
void LoadBank(const std::string& name);
void UnloadBank(const std::string& name);
void UnloadAllBanks();
-
SoundEvent PlayEvent(const std::string& name);
-
void Update(float deltaTime);
-
// For positional audio
- void SetListener(const Matrix4& viewMatrix);
+ void SetListener(const Matrix4& viewMatrix, const Vector3& velocity = Vector3::Zero);
// Control buses
float GetBusVolume(const std::string& name) const;
bool GetBusPaused(const std::string& name) const;
@@ -57,8 +52,7 @@ class AudioSystem
private:
// Tracks the next ID to use for event instances
static unsigned int sNextID;
-
- class Game* mGame;
+ class Game* pGame;
// Map of loaded banks
std::unordered_map mBanks;
// Map of event name to EventDescription
@@ -68,7 +62,7 @@ class AudioSystem
// Map of buses
std::unordered_map mBuses;
// FMOD studio system
- FMOD::Studio::System* mSystem;
- // FMOD Low-level system (in case needed)
- FMOD::System* mLowLevelSystem;
+ FMOD::Studio::System* pSystem;
+ // FMOD core system (in case needed)
+ FMOD::System* pCoreSystem;
};
\ No newline at end of file
diff --git a/Chapter07/CameraActor.cpp b/Chapter07/CameraActor.cpp
index ec43a95f..32d910b9 100644
--- a/Chapter07/CameraActor.cpp
+++ b/Chapter07/CameraActor.cpp
@@ -14,29 +14,26 @@
#include "Game.h"
#include "AudioComponent.h"
-CameraActor::CameraActor(Game* game)
- :Actor(game)
+CameraActor::CameraActor(Game* game): Actor(game)
{
- mMoveComp = new MoveComponent(this);
- mAudioComp = new AudioComponent(this);
+ pMoveComp = new MoveComponent(this);
+ pAudioComp = new AudioComponent(this);
mLastFootstep = 0.0f;
- mFootstep = mAudioComp->PlayEvent("event:/Footstep");
+ mFootstep = pAudioComp->PlayEvent("event:/Footstep");
mFootstep.SetPaused(true);
}
void CameraActor::UpdateActor(float deltaTime)
{
Actor::UpdateActor(deltaTime);
-
// Play the footstep if we're moving and haven't recently
mLastFootstep -= deltaTime;
- if (!Math::NearZero(mMoveComp->GetForwardSpeed()) && mLastFootstep <= 0.0f)
+ if (!Math::NearZero(pMoveComp->GetForwardSpeed()) && mLastFootstep <= 0.0f)
{
mFootstep.SetPaused(false);
mFootstep.Restart();
mLastFootstep = 0.5f;
}
-
// Compute new camera from this actor
Vector3 cameraPos = GetPosition();
Vector3 target = GetPosition() + GetForward() * 100.0f;
@@ -67,15 +64,13 @@ void CameraActor::ActorInput(const uint8_t* keys)
{
angularSpeed += Math::TwoPi;
}
-
- mMoveComp->SetForwardSpeed(forwardSpeed);
- mMoveComp->SetAngularSpeed(angularSpeed);
+ pMoveComp->SetForwardSpeed(forwardSpeed);
+ pMoveComp->SetAngularSpeed(angularSpeed);
}
void CameraActor::SetFootstepSurface(float value)
{
- // Pause here because the way I setup the parameter in FMOD
- // changing it will play a footstep
+ // Pause here because the way I setup the parameter in FMOD changing it will play a footstep
mFootstep.SetPaused(true);
mFootstep.SetParameter("Surface", value);
-}
+}
\ No newline at end of file
diff --git a/Chapter07/CameraActor.h b/Chapter07/CameraActor.h
index 7c95d106..502f9b14 100644
--- a/Chapter07/CameraActor.h
+++ b/Chapter07/CameraActor.h
@@ -10,18 +10,16 @@
#include "Actor.h"
#include "SoundEvent.h"
-class CameraActor : public Actor
+class CameraActor: public Actor
{
public:
CameraActor(class Game* game);
-
void UpdateActor(float deltaTime) override;
void ActorInput(const uint8_t* keys) override;
-
void SetFootstepSurface(float value);
private:
- class MoveComponent* mMoveComp;
- class AudioComponent* mAudioComp;
+ class MoveComponent* pMoveComp;
+ class AudioComponent* pAudioComp;
SoundEvent mFootstep;
float mLastFootstep;
};
\ No newline at end of file
diff --git a/Chapter07/CircleComponent.cpp b/Chapter07/CircleComponent.cpp
index 4e40d109..f57bdd8a 100644
--- a/Chapter07/CircleComponent.cpp
+++ b/Chapter07/CircleComponent.cpp
@@ -9,21 +9,18 @@
#include "CircleComponent.h"
#include "Actor.h"
-CircleComponent::CircleComponent(class Actor* owner)
-:Component(owner)
-,mRadius(0.0f)
+CircleComponent::CircleComponent(class Actor* owner): Component(owner), mRadius(0.0f)
{
-
}
const Vector3& CircleComponent::GetCenter() const
{
- return mOwner->GetPosition();
+ return pOwner->GetPosition();
}
float CircleComponent::GetRadius() const
{
- return mOwner->GetScale() * mRadius;
+ return pOwner->GetScale() * mRadius;
}
bool Intersect(const CircleComponent& a, const CircleComponent& b)
@@ -31,10 +28,8 @@ bool Intersect(const CircleComponent& a, const CircleComponent& b)
// Calculate distance squared
Vector3 diff = a.GetCenter() - b.GetCenter();
float distSq = diff.LengthSq();
-
// Calculate sum of radii squared
float radiiSq = a.GetRadius() + b.GetRadius();
radiiSq *= radiiSq;
-
return distSq <= radiiSq;
-}
+}
\ No newline at end of file
diff --git a/Chapter07/CircleComponent.h b/Chapter07/CircleComponent.h
index 61c63ba9..57dda8ec 100644
--- a/Chapter07/CircleComponent.h
+++ b/Chapter07/CircleComponent.h
@@ -14,13 +14,11 @@ class CircleComponent : public Component
{
public:
CircleComponent(class Actor* owner);
-
void SetRadius(float radius) { mRadius = radius; }
float GetRadius() const;
-
const Vector3& GetCenter() const;
private:
float mRadius;
};
-bool Intersect(const CircleComponent& a, const CircleComponent& b);
+bool Intersect(const CircleComponent& a, const CircleComponent& b);
\ No newline at end of file
diff --git a/Chapter07/Component.cpp b/Chapter07/Component.cpp
index c4ed432d..5446d684 100644
--- a/Chapter07/Component.cpp
+++ b/Chapter07/Component.cpp
@@ -9,19 +9,17 @@
#include "Component.h"
#include "Actor.h"
-Component::Component(Actor* owner, int updateOrder)
- :mOwner(owner)
- ,mUpdateOrder(updateOrder)
+Component::Component(Actor* owner, int updateOrder): pOwner(owner), mUpdateOrder(updateOrder)
{
// Add to actor's vector of components
- mOwner->AddComponent(this);
+ pOwner->AddComponent(this);
}
Component::~Component()
{
- mOwner->RemoveComponent(this);
+ pOwner->RemoveComponent(this);
}
void Component::Update(float deltaTime)
{
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Component.h b/Chapter07/Component.h
index e2be424b..a72aa198 100644
--- a/Chapter07/Component.h
+++ b/Chapter07/Component.h
@@ -12,8 +12,7 @@
class Component
{
public:
- // Constructor
- // (the lower the update order, the earlier the component updates)
+ // Constructor (the lower the update order, the earlier the component updates)
Component(class Actor* owner, int updateOrder = 100);
// Destructor
virtual ~Component();
@@ -23,11 +22,10 @@ class Component
virtual void ProcessInput(const uint8_t* keyState) {}
// Called when world transform changes
virtual void OnUpdateWorldTransform() { }
-
int GetUpdateOrder() const { return mUpdateOrder; }
protected:
// Owning actor
- class Actor* mOwner;
+ class Actor* pOwner;
// Update order of component
int mUpdateOrder;
-};
+};
\ No newline at end of file
diff --git a/Chapter07/Game.cpp b/Chapter07/Game.cpp
index e2715eb9..5e7dd5bd 100644
--- a/Chapter07/Game.cpp
+++ b/Chapter07/Game.cpp
@@ -17,13 +17,8 @@
#include "PlaneActor.h"
#include "AudioComponent.h"
-Game::Game()
-:mRenderer(nullptr)
-,mAudioSystem(nullptr)
-,mIsRunning(true)
-,mUpdatingActors(false)
+Game::Game(): pRenderer(nullptr), pAudioSystem(nullptr), mIsRunning(true), mUpdatingActors(false)
{
-
}
bool Game::Initialize()
@@ -33,32 +28,27 @@ bool Game::Initialize()
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
return false;
}
-
// Create the renderer
- mRenderer = new Renderer(this);
- if (!mRenderer->Initialize(1024.0f, 768.0f))
+ pRenderer = new Renderer(this);
+ if (!pRenderer->Initialize(1024.0f, 768.0f))
{
SDL_Log("Failed to initialize renderer");
- delete mRenderer;
- mRenderer = nullptr;
+ delete pRenderer;
+ pRenderer = nullptr;
return false;
}
-
// Create the audio system
- mAudioSystem = new AudioSystem(this);
- if (!mAudioSystem->Initialize())
+ pAudioSystem = new AudioSystem(this);
+ if (!pAudioSystem->Initialize())
{
SDL_Log("Failed to initialize audio system");
- mAudioSystem->Shutdown();
- delete mAudioSystem;
- mAudioSystem = nullptr;
+ pAudioSystem->Shutdown();
+ delete pAudioSystem;
+ pAudioSystem = nullptr;
return false;
}
-
LoadData();
-
mTicksCount = SDL_GetTicks();
-
return true;
}
@@ -93,14 +83,12 @@ void Game::ProcessInput()
break;
}
}
-
const Uint8* state = SDL_GetKeyboardState(NULL);
if (state[SDL_SCANCODE_ESCAPE])
{
mIsRunning = false;
}
-
- for (auto actor : mActors)
+ for (auto actor: mActors)
{
actor->ProcessInput(state);
}
@@ -113,22 +101,22 @@ void Game::HandleKeyPress(int key)
case '-':
{
// Reduce master volume
- float volume = mAudioSystem->GetBusVolume("bus:/");
+ float volume = pAudioSystem->GetBusVolume("bus:/");
volume = Math::Max(0.0f, volume - 0.1f);
- mAudioSystem->SetBusVolume("bus:/", volume);
+ pAudioSystem->SetBusVolume("bus:/", volume);
break;
}
case '=':
{
// Increase master volume
- float volume = mAudioSystem->GetBusVolume("bus:/");
+ float volume = pAudioSystem->GetBusVolume("bus:/");
volume = Math::Min(1.0f, volume + 0.1f);
- mAudioSystem->SetBusVolume("bus:/", volume);
+ pAudioSystem->SetBusVolume("bus:/", volume);
break;
}
case 'e':
// Play explosion
- mAudioSystem->PlayEvent("event:/Explosion2D");
+ pAudioSystem->PlayEvent("event:/Explosion2D");
break;
case 'm':
// Toggle music pause state
@@ -138,7 +126,7 @@ void Game::HandleKeyPress(int key)
// Stop or start reverb snapshot
if (!mReverbSnap.IsValid())
{
- mReverbSnap = mAudioSystem->PlayEvent("snapshot:/WithReverb");
+ mReverbSnap = pAudioSystem->PlayEvent("snapshot:/WithReverb");
}
else
{
@@ -147,11 +135,11 @@ void Game::HandleKeyPress(int key)
break;
case '1':
// Set default footstep surface
- mCameraActor->SetFootstepSurface(0.0f);
+ pCameraActor->SetFootstepSurface(0.0f);
break;
case '2':
// Set grass footstep surface
- mCameraActor->SetFootstepSurface(0.5f);
+ pCameraActor->SetFootstepSurface(0.5f);
break;
default:
break;
@@ -162,55 +150,64 @@ void Game::UpdateGame()
{
// Compute delta time
// Wait until 16ms has elapsed since last frame
- while (!SDL_TICKS_PASSED(SDL_GetTicks(), mTicksCount + 16))
- ;
-
+ while (!SDL_TICKS_PASSED(SDL_GetTicks(), mTicksCount + 16));
float deltaTime = (SDL_GetTicks() - mTicksCount) / 1000.0f;
if (deltaTime > 0.05f)
{
deltaTime = 0.05f;
}
mTicksCount = SDL_GetTicks();
-
- // Update all actors
+// Update all actors:
mUpdatingActors = true;
- for (auto actor : mActors)
+ // Update custom Sphere actor
+ Vector3 pos = pSphereActor->GetPosition();
+ if(mDirection && (pos.y >= -1000))
+ {
+ pos.y -= 5;
+ }
+ else if(!mDirection && pos.y <= 1000)
+ {
+ pos.y += 5;
+ }
+ else
+ {
+ mDirection = !mDirection;
+ }
+ pSphereActor->SetPosition(pos);
+ // Update the normal/alive actors
+ for (auto actor: mActors)
{
actor->Update(deltaTime);
}
mUpdatingActors = false;
-
// Move any pending actors to mActors
- for (auto pending : mPendingActors)
+ for (auto pending: mPendingActors)
{
pending->ComputeWorldTransform();
mActors.emplace_back(pending);
}
mPendingActors.clear();
-
// Add any dead actors to a temp vector
std::vector deadActors;
- for (auto actor : mActors)
+ for (auto actor: mActors)
{
if (actor->GetState() == Actor::EDead)
{
deadActors.emplace_back(actor);
}
}
-
// Delete dead actors (which removes them from mActors)
- for (auto actor : deadActors)
+ for (auto actor: deadActors)
{
delete actor;
}
-
// Update audio system
- mAudioSystem->Update(deltaTime);
+ pAudioSystem->Update(deltaTime);
}
void Game::GenerateOutput()
{
- mRenderer->Draw();
+ pRenderer->Draw();
}
void Game::LoadData()
@@ -223,14 +220,12 @@ void Game::LoadData()
q = Quaternion::Concatenate(q, Quaternion(Vector3::UnitZ, Math::Pi + Math::Pi / 4.0f));
a->SetRotation(q);
MeshComponent* mc = new MeshComponent(a);
- mc->SetMesh(mRenderer->GetMesh("Assets/Cube.gpmesh"));
-
+ mc->SetMesh(pRenderer->GetMesh("Assets/Cube.gpmesh"));
a = new Actor(this);
a->SetPosition(Vector3(200.0f, -75.0f, 0.0f));
a->SetScale(3.0f);
mc = new MeshComponent(a);
- mc->SetMesh(mRenderer->GetMesh("Assets/Sphere.gpmesh"));
-
+ mc->SetMesh(pRenderer->GetMesh("Assets/Sphere.gpmesh"));
// Setup floor
const float start = -1250.0f;
const float size = 250.0f;
@@ -242,7 +237,6 @@ void Game::LoadData()
a->SetPosition(Vector3(start + i * size, start + j * size, -100.0f));
}
}
-
// Left/right walls
q = Quaternion(Vector3::UnitX, Math::PiOver2);
for (int i = 0; i < 10; i++)
@@ -250,12 +244,10 @@ void Game::LoadData()
a = new PlaneActor(this);
a->SetPosition(Vector3(start + i * size, start - size, 0.0f));
a->SetRotation(q);
-
a = new PlaneActor(this);
a->SetPosition(Vector3(start + i * size, -start + size, 0.0f));
a->SetRotation(q);
}
-
q = Quaternion::Concatenate(q, Quaternion(Vector3::UnitZ, Math::PiOver2));
// Forward/back walls
for (int i = 0; i < 10; i++)
@@ -263,45 +255,38 @@ void Game::LoadData()
a = new PlaneActor(this);
a->SetPosition(Vector3(start - size, start + i * size, 0.0f));
a->SetRotation(q);
-
a = new PlaneActor(this);
a->SetPosition(Vector3(-start + size, start + i * size, 0.0f));
a->SetRotation(q);
}
-
// Setup lights
- mRenderer->SetAmbientLight(Vector3(0.2f, 0.2f, 0.2f));
- DirectionalLight& dir = mRenderer->GetDirectionalLight();
+ pRenderer->SetAmbientLight(Vector3(0.2f, 0.2f, 0.2f));
+ DirectionalLight& dir = pRenderer->GetDirectionalLight();
dir.mDirection = Vector3(0.0f, -0.707f, -0.707f);
dir.mDiffuseColor = Vector3(0.78f, 0.88f, 1.0f);
dir.mSpecColor = Vector3(0.8f, 0.8f, 0.8f);
-
// Camera actor
- mCameraActor = new CameraActor(this);
-
+ pCameraActor = new CameraActor(this);
// UI elements
a = new Actor(this);
a->SetPosition(Vector3(-350.0f, -350.0f, 0.0f));
SpriteComponent* sc = new SpriteComponent(a);
- sc->SetTexture(mRenderer->GetTexture("Assets/HealthBar.png"));
-
+ sc->SetTexture(pRenderer->GetTexture("Assets/HealthBar.png"));
a = new Actor(this);
a->SetPosition(Vector3(375.0f, -275.0f, 0.0f));
a->SetScale(0.75f);
sc = new SpriteComponent(a);
- sc->SetTexture(mRenderer->GetTexture("Assets/Radar.png"));
-
+ sc->SetTexture(pRenderer->GetTexture("Assets/Radar.png"));
// Create spheres with audio components playing different sounds
- a = new Actor(this);
- a->SetPosition(Vector3(500.0f, -75.0f, 0.0f));
- a->SetScale(1.0f);
- mc = new MeshComponent(a);
- mc->SetMesh(mRenderer->GetMesh("Assets/Sphere.gpmesh"));
- AudioComponent* ac = new AudioComponent(a);
+ pSphereActor = new Actor(this);
+ pSphereActor->SetPosition(Vector3(500.0f, -75.0f, 0.0f));
+ pSphereActor->SetScale(1.0f);
+ mc = new MeshComponent(pSphereActor);
+ mc->SetMesh(pRenderer->GetMesh("Assets/Sphere.gpmesh"));
+ AudioComponent* ac = new AudioComponent(pSphereActor);
ac->PlayEvent("event:/FireLoop");
-
// Start music
- mMusicEvent = mAudioSystem->PlayEvent("event:/Music");
+ mMusicEvent = pAudioSystem->PlayEvent("event:/Music");
}
void Game::UnloadData()
@@ -312,23 +297,22 @@ void Game::UnloadData()
{
delete mActors.back();
}
-
- if (mRenderer)
+ if (pRenderer)
{
- mRenderer->UnloadData();
+ pRenderer->UnloadData();
}
}
void Game::Shutdown()
{
UnloadData();
- if (mRenderer)
+ if (pRenderer)
{
- mRenderer->Shutdown();
+ pRenderer->Shutdown();
}
- if (mAudioSystem)
+ if (pAudioSystem)
{
- mAudioSystem->Shutdown();
+ pAudioSystem->Shutdown();
}
SDL_Quit();
}
@@ -356,7 +340,6 @@ void Game::RemoveActor(Actor* actor)
std::iter_swap(iter, mPendingActors.end() - 1);
mPendingActors.pop_back();
}
-
// Is it in actors?
iter = std::find(mActors.begin(), mActors.end(), actor);
if (iter != mActors.end())
@@ -365,4 +348,4 @@ void Game::RemoveActor(Actor* actor)
std::iter_swap(iter, mActors.end() - 1);
mActors.pop_back();
}
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Game.h b/Chapter07/Game.h
index 12825f7c..91b76754 100644
--- a/Chapter07/Game.h
+++ b/Chapter07/Game.h
@@ -21,12 +21,10 @@ class Game
bool Initialize();
void RunLoop();
void Shutdown();
-
void AddActor(class Actor* actor);
void RemoveActor(class Actor* actor);
-
- class Renderer* GetRenderer() { return mRenderer; }
- class AudioSystem* GetAudioSystem() { return mAudioSystem; }
+ class Renderer* GetRenderer() { return pRenderer; }
+ class AudioSystem* GetAudioSystem() { return pAudioSystem; }
private:
void ProcessInput();
void HandleKeyPress(int key);
@@ -34,22 +32,21 @@ class Game
void GenerateOutput();
void LoadData();
void UnloadData();
-
// All the actors in the game
std::vector mActors;
// Any pending actors
std::vector mPendingActors;
-
- class Renderer* mRenderer;
- class AudioSystem* mAudioSystem;
-
+ // Pointer to a specific Sphere actor
+ class Actor* pSphereActor;
+ bool mDirection;
+ class Renderer* pRenderer;
+ class AudioSystem* pAudioSystem;
Uint32 mTicksCount;
bool mIsRunning;
// Track if we're updating actors right now
bool mUpdatingActors;
-
// Game-specific code
- class CameraActor* mCameraActor;
+ class CameraActor* pCameraActor;
SoundEvent mMusicEvent;
SoundEvent mReverbSnap;
-};
+};
\ No newline at end of file
diff --git a/Chapter07/Game.vcxproj b/Chapter07/Game.vcxproj
index e14fa8e5..dc5a0881 100644
--- a/Chapter07/Game.vcxproj
+++ b/Chapter07/Game.vcxproj
@@ -63,19 +63,19 @@
{BC508D87-495F-4554-932D-DD68388B63CC}
Win32Proj
Game
- 10.0.16299.0
+ 10.0
Application
true
- v141
+ v143
Unicode
Application
false
- v141
+ v143
true
Unicode
@@ -102,23 +102,23 @@
Disabled
WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
true
- ..\external\SDL\include;..\external\GLEW\include;..\external\SOIL\include;..\external\rapidjson\include;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\inc;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\lowlevel\inc;%(AdditionalIncludeDirectories)
+ ..\external\SDL\include;..\external\GLEW\include;..\external\SOIL\include;..\external\rapidjson\include;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\inc;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\inc;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\fsbank\inc;%(AdditionalIncludeDirectories)
false
Sync
Console
true
- ..\external\SDL\lib\win\x86;..\external\GLEW\lib\win\x86;..\external\SOIL\lib\win\x86;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\lowlevel\lib;%(AdditionalLibraryDirectories)
+ ..\external\SDL\lib\win\x86;..\external\GLEW\lib\win\x86;..\external\SOIL\lib\win\x86;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\fsbank\lib\x86;%(AdditionalLibraryDirectories)
opengl32.lib;SDL2.lib;SDL2main.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_image.lib;glew32.lib;SOIL.lib;fmodL_vc.lib;fmodstudioL_vc.lib;%(AdditionalDependencies)
/NODEFAULTLIB:msvcrt.lib %(AdditionalOptions)
xcopy "$(ProjectDir)\..\external\SDL\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "$(ProjectDir)\..\external\GLEW\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
-xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\lowlevel\lib\*.dll" "$(OutDir)" /i /s /y
-xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\*.dll" "$(OutDir)" /i /s /y
-
+xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86\*.dll" "$(OutDir)" /i /s /y
+xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86\*.dll" "$(OutDir)" /i /s /y
+xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\fsbank\lib\x86\*.dll" "$(OutDir)" /i /s /y
@@ -130,7 +130,7 @@ xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studi
true
WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
true
- ..\external\SDL\include;..\external\GLEW\include;..\external\SOIL\include;..\external\rapidjson\include;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\inc;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\lowlevel\inc;%(AdditionalIncludeDirectories)
+ ..\external\SDL\include;..\external\GLEW\include;..\external\SOIL\include;..\external\rapidjson\include;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\inc;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\inc;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\fsbank\inc;%(AdditionalIncludeDirectories)
false
Sync
@@ -139,15 +139,15 @@ xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studi
true
true
true
- ..\external\SDL\lib\win\x86;..\external\GLEW\lib\win\x86;..\external\SOIL\lib\win\x86;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\lowlevel\lib;%(AdditionalLibraryDirectories)
+ ..\external\SDL\lib\win\x86;..\external\GLEW\lib\win\x86;..\external\SOIL\lib\win\x86;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86;C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\fsbank\lib\x86;%(AdditionalLibraryDirectories)
opengl32.lib;SDL2.lib;SDL2main.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_image.lib;glew32.lib;SOIL.lib;fmodL_vc.lib;fmodstudioL_vc.lib;%(AdditionalDependencies)
xcopy "$(ProjectDir)\..\external\SDL\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
xcopy "$(ProjectDir)\..\external\GLEW\lib\win\x86\*.dll" "$(OutDir)" /i /s /y
-xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\lowlevel\lib\*.dll" "$(OutDir)" /i /s /y
-xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\*.dll" "$(OutDir)" /i /s /y
-
+xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86\*.dll" "$(OutDir)" /i /s /y
+xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\studio\lib\x86\*.dll" "$(OutDir)" /i /s /y
+xcopy "C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\fsbank\lib\x86\*.dll" "$(OutDir)" /i /s /y
diff --git a/Chapter07/Main.cpp b/Chapter07/Main.cpp
index 22ea0c69..625e0599 100644
--- a/Chapter07/Main.cpp
+++ b/Chapter07/Main.cpp
@@ -18,4 +18,4 @@ int main(int argc, char** argv)
}
game.Shutdown();
return 0;
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Math.cpp b/Chapter07/Math.cpp
index a16e7261..1435e4a9 100644
--- a/Chapter07/Math.cpp
+++ b/Chapter07/Math.cpp
@@ -39,7 +39,6 @@ static float m4Ident[4][4] =
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
};
-
const Matrix4 Matrix4::Identity(m4Ident);
const Quaternion Quaternion::Identity(0.0f, 0.0f, 0.0f, 1.0f);
@@ -56,12 +55,9 @@ Vector2 Vector2::Transform(const Vector2& vec, const Matrix3& mat, float w /*= 1
Vector3 Vector3::Transform(const Vector3& vec, const Matrix4& mat, float w /*= 1.0f*/)
{
Vector3 retVal;
- retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] +
- vec.z * mat.mat[2][0] + w * mat.mat[3][0];
- retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] +
- vec.z * mat.mat[2][1] + w * mat.mat[3][1];
- retVal.z = vec.x * mat.mat[0][2] + vec.y * mat.mat[1][2] +
- vec.z * mat.mat[2][2] + w * mat.mat[3][2];
+ retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] + vec.z * mat.mat[2][0] + w * mat.mat[3][0];
+ retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] + vec.z * mat.mat[2][1] + w * mat.mat[3][1];
+ retVal.z = vec.x * mat.mat[0][2] + vec.y * mat.mat[1][2] + vec.z * mat.mat[2][2] + w * mat.mat[3][2];
//ignore w since we aren't returning a new value for it...
return retVal;
}
@@ -70,14 +66,10 @@ Vector3 Vector3::Transform(const Vector3& vec, const Matrix4& mat, float w /*= 1
Vector3 Vector3::TransformWithPerspDiv(const Vector3& vec, const Matrix4& mat, float w /*= 1.0f*/)
{
Vector3 retVal;
- retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] +
- vec.z * mat.mat[2][0] + w * mat.mat[3][0];
- retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] +
- vec.z * mat.mat[2][1] + w * mat.mat[3][1];
- retVal.z = vec.x * mat.mat[0][2] + vec.y * mat.mat[1][2] +
- vec.z * mat.mat[2][2] + w * mat.mat[3][2];
- float transformedW = vec.x * mat.mat[0][3] + vec.y * mat.mat[1][3] +
- vec.z * mat.mat[2][3] + w * mat.mat[3][3];
+ retVal.x = vec.x * mat.mat[0][0] + vec.y * mat.mat[1][0] + vec.z * mat.mat[2][0] + w * mat.mat[3][0];
+ retVal.y = vec.x * mat.mat[0][1] + vec.y * mat.mat[1][1] + vec.z * mat.mat[2][1] + w * mat.mat[3][1];
+ retVal.z = vec.x * mat.mat[0][2] + vec.y * mat.mat[1][2] + vec.z * mat.mat[2][2] + w * mat.mat[3][2];
+ float transformedW = vec.x * mat.mat[0][3] + vec.y * mat.mat[1][3] + vec.z * mat.mat[2][3] + w * mat.mat[3][3];
if (!Math::NearZero(Math::Abs(transformedW)))
{
transformedW = 1.0f / transformedW;
@@ -104,33 +96,28 @@ void Matrix4::Invert()
float src[16];
float dst[16];
float det;
-
- // Transpose matrix
+// Transpose matrix:
// row 1 to col 1
src[0] = mat[0][0];
src[4] = mat[0][1];
src[8] = mat[0][2];
src[12] = mat[0][3];
-
// row 2 to col 2
src[1] = mat[1][0];
src[5] = mat[1][1];
src[9] = mat[1][2];
src[13] = mat[1][3];
-
// row 3 to col 3
src[2] = mat[2][0];
src[6] = mat[2][1];
src[10] = mat[2][2];
src[14] = mat[2][3];
-
// row 4 to col 4
src[3] = mat[3][0];
src[7] = mat[3][1];
src[11] = mat[3][2];
src[15] = mat[3][3];
-
- // Calculate cofactors
+// Calculate cofactors:
tmp[0] = src[10] * src[15];
tmp[1] = src[11] * src[14];
tmp[2] = src[9] * src[15];
@@ -143,7 +130,6 @@ void Matrix4::Invert()
tmp[9] = src[10] * src[12];
tmp[10] = src[8] * src[13];
tmp[11] = src[9] * src[12];
-
dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7];
dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7];
dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7];
@@ -160,7 +146,6 @@ void Matrix4::Invert()
dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3];
dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2];
dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2];
-
tmp[0] = src[2] * src[7];
tmp[1] = src[3] * src[6];
tmp[2] = src[1] * src[7];
@@ -173,7 +158,6 @@ void Matrix4::Invert()
tmp[9] = src[2] * src[4];
tmp[10] = src[0] * src[5];
tmp[11] = src[1] * src[4];
-
dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15];
dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15];
dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15];
@@ -190,17 +174,14 @@ void Matrix4::Invert()
dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9];
dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9];
dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8];
-
// Calculate determinant
det = src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3] * dst[3];
-
// Inverse of matrix is divided by determinant
det = 1 / det;
for (int j = 0; j < 16; j++)
{
dst[j] *= det;
}
-
// Set it back
for (int i = 0; i < 4; i++)
{
@@ -214,26 +195,21 @@ void Matrix4::Invert()
Matrix4 Matrix4::CreateFromQuaternion(const class Quaternion& q)
{
float mat[4][4];
-
mat[0][0] = 1.0f - 2.0f * q.y * q.y - 2.0f * q.z * q.z;
mat[0][1] = 2.0f * q.x * q.y + 2.0f * q.w * q.z;
mat[0][2] = 2.0f * q.x * q.z - 2.0f * q.w * q.y;
mat[0][3] = 0.0f;
-
mat[1][0] = 2.0f * q.x * q.y - 2.0f * q.w * q.z;
mat[1][1] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.z * q.z;
mat[1][2] = 2.0f * q.y * q.z + 2.0f * q.w * q.x;
mat[1][3] = 0.0f;
-
mat[2][0] = 2.0f * q.x * q.z + 2.0f * q.w * q.y;
mat[2][1] = 2.0f * q.y * q.z - 2.0f * q.w * q.x;
mat[2][2] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.y * q.y;
mat[2][3] = 0.0f;
-
mat[3][0] = 0.0f;
mat[3][1] = 0.0f;
mat[3][2] = 0.0f;
mat[3][3] = 1.0f;
-
return Matrix4(mat);
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Math.h b/Chapter07/Math.h
index 752963f1..44666a0d 100644
--- a/Chapter07/Math.h
+++ b/Chapter07/Math.h
@@ -24,12 +24,10 @@ namespace Math
{
return degrees * Pi / 180.0f;
}
-
inline float ToDegrees(float radians)
{
return radians * 180.0f / Pi;
}
-
inline bool NearZero(float val, float epsilon = 0.001f)
{
if (fabs(val) <= epsilon)
@@ -41,70 +39,57 @@ namespace Math
return false;
}
}
-
template
T Max(const T& a, const T& b)
{
return (a < b ? b : a);
}
-
template
T Min(const T& a, const T& b)
{
return (a < b ? a : b);
}
-
template
T Clamp(const T& value, const T& lower, const T& upper)
{
return Min(upper, Max(lower, value));
}
-
inline float Abs(float value)
{
return fabs(value);
}
-
inline float Cos(float angle)
{
return cosf(angle);
}
-
inline float Sin(float angle)
{
return sinf(angle);
}
-
inline float Tan(float angle)
{
return tanf(angle);
}
-
inline float Acos(float value)
{
return acosf(value);
}
-
inline float Atan2(float y, float x)
{
return atan2f(y, x);
}
-
inline float Cot(float angle)
{
return 1.0f / Tan(angle);
}
-
inline float Lerp(float a, float b, float f)
{
return a + f * (b - a);
}
-
inline float Sqrt(float value)
{
return sqrtf(value);
}
-
inline float Fmod(float numer, float denom)
{
return fmod(numer, denom);
@@ -118,54 +103,41 @@ class Vector2
float x;
float y;
- Vector2()
- :x(0.0f)
- ,y(0.0f)
+ Vector2(): x(0.0f), y(0.0f)
{}
-
- explicit Vector2(float inX, float inY)
- :x(inX)
- ,y(inY)
+ explicit Vector2(float inX, float inY): x(inX), y(inY)
{}
-
// Set both components in one line
void Set(float inX, float inY)
{
x = inX;
y = inY;
}
-
// Vector addition (a + b)
friend Vector2 operator+(const Vector2& a, const Vector2& b)
{
return Vector2(a.x + b.x, a.y + b.y);
}
-
// Vector subtraction (a - b)
friend Vector2 operator-(const Vector2& a, const Vector2& b)
{
return Vector2(a.x - b.x, a.y - b.y);
}
-
// Component-wise multiplication
- // (a.x * b.x, ...)
friend Vector2 operator*(const Vector2& a, const Vector2& b)
{
return Vector2(a.x * b.x, a.y * b.y);
}
-
// Scalar multiplication
friend Vector2 operator*(const Vector2& vec, float scalar)
{
return Vector2(vec.x * scalar, vec.y * scalar);
}
-
// Scalar multiplication
friend Vector2 operator*(float scalar, const Vector2& vec)
{
return Vector2(vec.x * scalar, vec.y * scalar);
}
-
// Scalar *=
Vector2& operator*=(float scalar)
{
@@ -173,7 +145,6 @@ class Vector2
y *= scalar;
return *this;
}
-
// Vector +=
Vector2& operator+=(const Vector2& right)
{
@@ -181,7 +152,6 @@ class Vector2
y += right.y;
return *this;
}
-
// Vector -=
Vector2& operator-=(const Vector2& right)
{
@@ -189,19 +159,16 @@ class Vector2
y -= right.y;
return *this;
}
-
// Length squared of vector
float LengthSq() const
{
return (x*x + y*y);
}
-
// Length of vector
float Length() const
{
return (Math::Sqrt(LengthSq()));
}
-
// Normalize this vector
void Normalize()
{
@@ -209,7 +176,6 @@ class Vector2
x /= length;
y /= length;
}
-
// Normalize the provided vector
static Vector2 Normalize(const Vector2& vec)
{
@@ -217,25 +183,21 @@ class Vector2
temp.Normalize();
return temp;
}
-
// Dot product between two vectors (a dot b)
static float Dot(const Vector2& a, const Vector2& b)
{
return (a.x * b.x + a.y * b.y);
}
-
// Lerp from A to B by f
static Vector2 Lerp(const Vector2& a, const Vector2& b, float f)
{
return Vector2(a + f * (b - a));
}
-
// Reflect V about (normalized) N
static Vector2 Reflect(const Vector2& v, const Vector2& n)
{
return v - 2.0f * Vector2::Dot(v, n) * n;
}
-
// Transform vector by matrix
static Vector2 Transform(const Vector2& vec, const class Matrix3& mat, float w = 1.0f);
@@ -254,24 +216,15 @@ class Vector3
float y;
float z;
- Vector3()
- :x(0.0f)
- ,y(0.0f)
- ,z(0.0f)
+ Vector3(): x(0.0f), y(0.0f), z(0.0f)
{}
-
- explicit Vector3(float inX, float inY, float inZ)
- :x(inX)
- ,y(inY)
- ,z(inZ)
+ explicit Vector3(float inX, float inY, float inZ): x(inX), y(inY), z(inZ)
{}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&x);
}
-
// Set all three components in one line
void Set(float inX, float inY, float inZ)
{
@@ -279,37 +232,31 @@ class Vector3
y = inY;
z = inZ;
}
-
// Vector addition (a + b)
friend Vector3 operator+(const Vector3& a, const Vector3& b)
{
return Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
}
-
// Vector subtraction (a - b)
friend Vector3 operator-(const Vector3& a, const Vector3& b)
{
return Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
}
-
// Component-wise multiplication
friend Vector3 operator*(const Vector3& left, const Vector3& right)
{
return Vector3(left.x * right.x, left.y * right.y, left.z * right.z);
}
-
// Scalar multiplication
friend Vector3 operator*(const Vector3& vec, float scalar)
{
return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
}
-
// Scalar multiplication
friend Vector3 operator*(float scalar, const Vector3& vec)
{
return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
}
-
// Scalar *=
Vector3& operator*=(float scalar)
{
@@ -318,7 +265,6 @@ class Vector3
z *= scalar;
return *this;
}
-
// Vector +=
Vector3& operator+=(const Vector3& right)
{
@@ -327,7 +273,6 @@ class Vector3
z += right.z;
return *this;
}
-
// Vector -=
Vector3& operator-=(const Vector3& right)
{
@@ -336,19 +281,26 @@ class Vector3
z -= right.z;
return *this;
}
-
+ // Vector ==
+ bool operator==(const Vector3& right)
+ {
+ return ((x == right.x) && (y == right.y) && (z == right.z));
+ }
+ // Vector !=
+ bool operator!=(const Vector3& right)
+ {
+ return !((x == right.x) && (y == right.y) && (z == right.z));
+ }
// Length squared of vector
float LengthSq() const
{
return (x*x + y*y + z*z);
}
-
// Length of vector
float Length() const
{
return (Math::Sqrt(LengthSq()));
}
-
// Normalize this vector
void Normalize()
{
@@ -357,7 +309,6 @@ class Vector3
y /= length;
z /= length;
}
-
// Normalize the provided vector
static Vector3 Normalize(const Vector3& vec)
{
@@ -365,13 +316,11 @@ class Vector3
temp.Normalize();
return temp;
}
-
// Dot product between two vectors (a dot b)
static float Dot(const Vector3& a, const Vector3& b)
{
return (a.x * b.x + a.y * b.y + a.z * b.z);
}
-
// Cross product between two vectors (a cross b)
static Vector3 Cross(const Vector3& a, const Vector3& b)
{
@@ -381,23 +330,19 @@ class Vector3
temp.z = a.x * b.y - a.y * b.x;
return temp;
}
-
// Lerp from A to B by f
static Vector3 Lerp(const Vector3& a, const Vector3& b, float f)
{
return Vector3(a + f * (b - a));
}
-
// Reflect V about (normalized) N
static Vector3 Reflect(const Vector3& v, const Vector3& n)
{
return v - 2.0f * Vector3::Dot(v, n) * n;
}
-
static Vector3 Transform(const Vector3& vec, const class Matrix4& mat, float w = 1.0f);
// This will transform the vector and renormalize the w component
static Vector3 TransformWithPerspDiv(const Vector3& vec, const class Matrix4& mat, float w = 1.0f);
-
// Transform a Vector3 by a quaternion
static Vector3 Transform(const Vector3& v, const class Quaternion& q);
@@ -422,18 +367,15 @@ class Matrix3
{
*this = Matrix3::Identity;
}
-
explicit Matrix3(float inMat[3][3])
{
memcpy(mat, inMat, 9 * sizeof(float));
}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&mat[0][0]);
}
-
// Matrix multiplication
friend Matrix3 operator*(const Matrix3& left, const Matrix3& right)
{
@@ -443,58 +385,47 @@ class Matrix3
left.mat[0][0] * right.mat[0][0] +
left.mat[0][1] * right.mat[1][0] +
left.mat[0][2] * right.mat[2][0];
-
retVal.mat[0][1] =
left.mat[0][0] * right.mat[0][1] +
left.mat[0][1] * right.mat[1][1] +
left.mat[0][2] * right.mat[2][1];
-
retVal.mat[0][2] =
left.mat[0][0] * right.mat[0][2] +
left.mat[0][1] * right.mat[1][2] +
left.mat[0][2] * right.mat[2][2];
-
// row 1
retVal.mat[1][0] =
left.mat[1][0] * right.mat[0][0] +
left.mat[1][1] * right.mat[1][0] +
left.mat[1][2] * right.mat[2][0];
-
retVal.mat[1][1] =
left.mat[1][0] * right.mat[0][1] +
left.mat[1][1] * right.mat[1][1] +
left.mat[1][2] * right.mat[2][1];
-
retVal.mat[1][2] =
left.mat[1][0] * right.mat[0][2] +
left.mat[1][1] * right.mat[1][2] +
left.mat[1][2] * right.mat[2][2];
-
// row 2
retVal.mat[2][0] =
left.mat[2][0] * right.mat[0][0] +
left.mat[2][1] * right.mat[1][0] +
left.mat[2][2] * right.mat[2][0];
-
retVal.mat[2][1] =
left.mat[2][0] * right.mat[0][1] +
left.mat[2][1] * right.mat[1][1] +
left.mat[2][2] * right.mat[2][1];
-
retVal.mat[2][2] =
left.mat[2][0] * right.mat[0][2] +
left.mat[2][1] * right.mat[1][2] +
left.mat[2][2] * right.mat[2][2];
-
return retVal;
}
-
Matrix3& operator*=(const Matrix3& right)
{
*this = *this * right;
return *this;
}
-
// Create a scale matrix with x and y scales
static Matrix3 CreateScale(float xScale, float yScale)
{
@@ -506,18 +437,15 @@ class Matrix3
};
return Matrix3(temp);
}
-
static Matrix3 CreateScale(const Vector2& scaleVector)
{
return CreateScale(scaleVector.x, scaleVector.y);
}
-
// Create a scale matrix with a uniform factor
static Matrix3 CreateScale(float scale)
{
return CreateScale(scale, scale);
}
-
// Create a rotation matrix about the Z axis
// theta is in radians
static Matrix3 CreateRotation(float theta)
@@ -530,7 +458,6 @@ class Matrix3
};
return Matrix3(temp);
}
-
// Create a translation matrix (on the xy-plane)
static Matrix3 CreateTranslation(const Vector2& trans)
{
@@ -556,18 +483,15 @@ class Matrix4
{
*this = Matrix4::Identity;
}
-
explicit Matrix4(float inMat[4][4])
{
memcpy(mat, inMat, 16 * sizeof(float));
}
-
// Cast to a const float pointer
const float* GetAsFloatPtr() const
{
return reinterpret_cast(&mat[0][0]);
}
-
// Matrix multiplication (a * b)
friend Matrix4 operator*(const Matrix4& a, const Matrix4& b)
{
@@ -578,136 +502,113 @@ class Matrix4
a.mat[0][1] * b.mat[1][0] +
a.mat[0][2] * b.mat[2][0] +
a.mat[0][3] * b.mat[3][0];
-
retVal.mat[0][1] =
a.mat[0][0] * b.mat[0][1] +
a.mat[0][1] * b.mat[1][1] +
a.mat[0][2] * b.mat[2][1] +
a.mat[0][3] * b.mat[3][1];
-
retVal.mat[0][2] =
a.mat[0][0] * b.mat[0][2] +
a.mat[0][1] * b.mat[1][2] +
a.mat[0][2] * b.mat[2][2] +
a.mat[0][3] * b.mat[3][2];
-
retVal.mat[0][3] =
a.mat[0][0] * b.mat[0][3] +
a.mat[0][1] * b.mat[1][3] +
a.mat[0][2] * b.mat[2][3] +
a.mat[0][3] * b.mat[3][3];
-
// row 1
retVal.mat[1][0] =
a.mat[1][0] * b.mat[0][0] +
a.mat[1][1] * b.mat[1][0] +
a.mat[1][2] * b.mat[2][0] +
a.mat[1][3] * b.mat[3][0];
-
retVal.mat[1][1] =
a.mat[1][0] * b.mat[0][1] +
a.mat[1][1] * b.mat[1][1] +
a.mat[1][2] * b.mat[2][1] +
a.mat[1][3] * b.mat[3][1];
-
retVal.mat[1][2] =
a.mat[1][0] * b.mat[0][2] +
a.mat[1][1] * b.mat[1][2] +
a.mat[1][2] * b.mat[2][2] +
a.mat[1][3] * b.mat[3][2];
-
retVal.mat[1][3] =
a.mat[1][0] * b.mat[0][3] +
a.mat[1][1] * b.mat[1][3] +
a.mat[1][2] * b.mat[2][3] +
a.mat[1][3] * b.mat[3][3];
-
// row 2
retVal.mat[2][0] =
a.mat[2][0] * b.mat[0][0] +
a.mat[2][1] * b.mat[1][0] +
a.mat[2][2] * b.mat[2][0] +
a.mat[2][3] * b.mat[3][0];
-
retVal.mat[2][1] =
a.mat[2][0] * b.mat[0][1] +
a.mat[2][1] * b.mat[1][1] +
a.mat[2][2] * b.mat[2][1] +
a.mat[2][3] * b.mat[3][1];
-
retVal.mat[2][2] =
a.mat[2][0] * b.mat[0][2] +
a.mat[2][1] * b.mat[1][2] +
a.mat[2][2] * b.mat[2][2] +
a.mat[2][3] * b.mat[3][2];
-
retVal.mat[2][3] =
a.mat[2][0] * b.mat[0][3] +
a.mat[2][1] * b.mat[1][3] +
a.mat[2][2] * b.mat[2][3] +
a.mat[2][3] * b.mat[3][3];
-
// row 3
retVal.mat[3][0] =
a.mat[3][0] * b.mat[0][0] +
a.mat[3][1] * b.mat[1][0] +
a.mat[3][2] * b.mat[2][0] +
a.mat[3][3] * b.mat[3][0];
-
retVal.mat[3][1] =
a.mat[3][0] * b.mat[0][1] +
a.mat[3][1] * b.mat[1][1] +
a.mat[3][2] * b.mat[2][1] +
a.mat[3][3] * b.mat[3][1];
-
retVal.mat[3][2] =
a.mat[3][0] * b.mat[0][2] +
a.mat[3][1] * b.mat[1][2] +
a.mat[3][2] * b.mat[2][2] +
a.mat[3][3] * b.mat[3][2];
-
retVal.mat[3][3] =
a.mat[3][0] * b.mat[0][3] +
a.mat[3][1] * b.mat[1][3] +
a.mat[3][2] * b.mat[2][3] +
a.mat[3][3] * b.mat[3][3];
-
return retVal;
}
-
Matrix4& operator*=(const Matrix4& right)
{
*this = *this * right;
return *this;
}
-
// Invert the matrix - super slow
void Invert();
-
// Get the translation component of the matrix
Vector3 GetTranslation() const
{
return Vector3(mat[3][0], mat[3][1], mat[3][2]);
}
-
// Get the X axis of the matrix (forward)
Vector3 GetXAxis() const
{
return Vector3::Normalize(Vector3(mat[0][0], mat[0][1], mat[0][2]));
}
-
// Get the Y axis of the matrix (left)
Vector3 GetYAxis() const
{
return Vector3::Normalize(Vector3(mat[1][0], mat[1][1], mat[1][2]));
}
-
// Get the Z axis of the matrix (up)
Vector3 GetZAxis() const
{
return Vector3::Normalize(Vector3(mat[2][0], mat[2][1], mat[2][2]));
}
-
// Extract the scale component from the matrix
Vector3 GetScale() const
{
@@ -717,7 +618,6 @@ class Matrix4
retVal.z = Vector3(mat[2][0], mat[2][1], mat[2][2]).Length();
return retVal;
}
-
// Create a scale matrix with x, y, and z scales
static Matrix4 CreateScale(float xScale, float yScale, float zScale)
{
@@ -730,18 +630,15 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateScale(const Vector3& scaleVector)
{
return CreateScale(scaleVector.x, scaleVector.y, scaleVector.z);
}
-
// Create a scale matrix with a uniform factor
static Matrix4 CreateScale(float scale)
{
return CreateScale(scale, scale, scale);
}
-
// Rotation about x-axis
static Matrix4 CreateRotationX(float theta)
{
@@ -754,7 +651,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Rotation about y-axis
static Matrix4 CreateRotationY(float theta)
{
@@ -767,7 +663,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Rotation about z-axis
static Matrix4 CreateRotationZ(float theta)
{
@@ -780,10 +675,8 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Create a rotation matrix from a quaternion
static Matrix4 CreateFromQuaternion(const class Quaternion& q);
-
static Matrix4 CreateTranslation(const Vector3& trans)
{
float temp[4][4] =
@@ -795,7 +688,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
{
Vector3 zaxis = Vector3::Normalize(target - eye);
@@ -805,7 +697,6 @@ class Matrix4
trans.x = -Vector3::Dot(xaxis, eye);
trans.y = -Vector3::Dot(yaxis, eye);
trans.z = -Vector3::Dot(zaxis, eye);
-
float temp[4][4] =
{
{ xaxis.x, yaxis.x, zaxis.x, 0.0f },
@@ -815,7 +706,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreateOrtho(float width, float height, float near, float far)
{
float temp[4][4] =
@@ -827,7 +717,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
static Matrix4 CreatePerspectiveFOV(float fovY, float width, float height, float near, float far)
{
float yScale = Math::Cot(fovY / 2.0f);
@@ -841,7 +730,6 @@ class Matrix4
};
return Matrix4(temp);
}
-
// Create "Simple" View-Projection Matrix from Chapter 6
static Matrix4 CreateSimpleViewProj(float width, float height)
{
@@ -871,17 +759,13 @@ class Quaternion
{
*this = Quaternion::Identity;
}
-
- // This directly sets the quaternion components --
- // don't use for axis/angle
+ // This directly sets the quaternion components -- don't use for axis/angle
explicit Quaternion(float inX, float inY, float inZ, float inW)
{
Set(inX, inY, inZ, inW);
}
-
- // Construct the quaternion from an axis and angle
- // It is assumed that axis is already normalized,
- // and the angle is in radians
+ /* Construct the quaternion from an axis and angle
+ NOTE: It is assumed that axis is already normalized, and the angle is in radians*/
explicit Quaternion(const Vector3& axis, float angle)
{
float scalar = Math::Sin(angle / 2.0f);
@@ -890,7 +774,6 @@ class Quaternion
z = axis.z * scalar;
w = Math::Cos(angle / 2.0f);
}
-
// Directly set the internal components
void Set(float inX, float inY, float inZ, float inW)
{
@@ -899,24 +782,20 @@ class Quaternion
z = inZ;
w = inW;
}
-
void Conjugate()
{
x *= -1.0f;
y *= -1.0f;
z *= -1.0f;
}
-
float LengthSq() const
{
return (x*x + y*y + z*z + w*w);
}
-
float Length() const
{
return Math::Sqrt(LengthSq());
}
-
void Normalize()
{
float length = Length();
@@ -925,7 +804,6 @@ class Quaternion
z /= length;
w /= length;
}
-
// Normalize the provided quaternion
static Quaternion Normalize(const Quaternion& q)
{
@@ -933,7 +811,6 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
// Linear interpolation
static Quaternion Lerp(const Quaternion& a, const Quaternion& b, float f)
{
@@ -945,25 +822,20 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
static float Dot(const Quaternion& a, const Quaternion& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}
-
// Spherical Linear Interpolation
static Quaternion Slerp(const Quaternion& a, const Quaternion& b, float f)
{
float rawCosm = Quaternion::Dot(a, b);
-
float cosom = -rawCosm;
if (rawCosm >= 0.0f)
{
cosom = rawCosm;
}
-
float scale0, scale1;
-
if (cosom < 0.9999f)
{
const float omega = Math::Acos(cosom);
@@ -973,17 +845,14 @@ class Quaternion
}
else
{
- // Use linear interpolation if the quaternions
- // are collinear
+ // Use linear interpolation if the quaternions are collinear
scale0 = 1.0f - f;
scale1 = f;
}
-
if (rawCosm < 0.0f)
{
scale1 = -scale1;
}
-
Quaternion retVal;
retVal.x = scale0 * a.x + scale1 * b.x;
retVal.y = scale0 * a.y + scale1 * b.y;
@@ -992,13 +861,11 @@ class Quaternion
retVal.Normalize();
return retVal;
}
-
// Concatenate
// Rotate by q FOLLOWED BY p
static Quaternion Concatenate(const Quaternion& q, const Quaternion& p)
{
Quaternion retVal;
-
// Vector component is:
// ps * qv + qs * pv + pv x qv
Vector3 qv(q.x, q.y, q.z);
@@ -1007,11 +874,9 @@ class Quaternion
retVal.x = newVec.x;
retVal.y = newVec.y;
retVal.z = newVec.z;
-
// Scalar component is:
// ps * qs - pv . qv
retVal.w = p.w * q.w - Vector3::Dot(pv, qv);
-
return retVal;
}
@@ -1030,4 +895,4 @@ namespace Color
static const Vector3 LightBlue(0.68f, 0.85f, 0.9f);
static const Vector3 LightPink(1.0f, 0.71f, 0.76f);
static const Vector3 LightGreen(0.56f, 0.93f, 0.56f);
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Mesh.cpp b/Chapter07/Mesh.cpp
index 125ef961..f8e87ac9 100644
--- a/Chapter07/Mesh.cpp
+++ b/Chapter07/Mesh.cpp
@@ -16,10 +16,7 @@
#include
#include "Math.h"
-Mesh::Mesh()
- :mVertexArray(nullptr)
- ,mRadius(0.0f)
- ,mSpecPower(100.0f)
+Mesh::Mesh(): pVertexArray(nullptr), mRadius(0.0f), mSpecPower(100.0f)
{
}
@@ -35,35 +32,27 @@ bool Mesh::Load(const std::string& fileName, Renderer* renderer)
SDL_Log("File not found: Mesh %s", fileName.c_str());
return false;
}
-
std::stringstream fileStream;
fileStream << file.rdbuf();
std::string contents = fileStream.str();
rapidjson::StringStream jsonStr(contents.c_str());
rapidjson::Document doc;
doc.ParseStream(jsonStr);
-
if (!doc.IsObject())
{
SDL_Log("Mesh %s is not valid json", fileName.c_str());
return false;
}
-
int ver = doc["version"].GetInt();
-
// Check the version
if (ver != 1)
{
SDL_Log("Mesh %s not version 1", fileName.c_str());
return false;
}
-
mShaderName = doc["shader"].GetString();
-
- // Skip the vertex format/shader for now
- // (This is changed in a later chapter's code)
+ // Skip the vertex format/shader for now (This is changed in a later chapter's code)
size_t vertSize = 8;
-
// Load textures
const rapidjson::Value& textures = doc["textures"];
if (!textures.IsArray() || textures.Size() < 1)
@@ -71,9 +60,7 @@ bool Mesh::Load(const std::string& fileName, Renderer* renderer)
SDL_Log("Mesh %s has no textures, there should be at least one", fileName.c_str());
return false;
}
-
mSpecPower = static_cast(doc["specularPower"].GetDouble());
-
for (rapidjson::SizeType i = 0; i < textures.Size(); i++)
{
// Is this texture already loaded?
@@ -91,7 +78,6 @@ bool Mesh::Load(const std::string& fileName, Renderer* renderer)
}
mTextures.emplace_back(t);
}
-
// Load in the vertices
const rapidjson::Value& vertsJson = doc["vertices"];
if (!vertsJson.IsArray() || vertsJson.Size() < 1)
@@ -99,7 +85,6 @@ bool Mesh::Load(const std::string& fileName, Renderer* renderer)
SDL_Log("Mesh %s has no vertices", fileName.c_str());
return false;
}
-
std::vector vertices;
vertices.reserve(vertsJson.Size() * vertSize);
mRadius = 0.0f;
@@ -112,20 +97,16 @@ bool Mesh::Load(const std::string& fileName, Renderer* renderer)
SDL_Log("Unexpected vertex format for %s", fileName.c_str());
return false;
}
-
Vector3 pos(vert[0].GetDouble(), vert[1].GetDouble(), vert[2].GetDouble());
mRadius = Math::Max(mRadius, pos.LengthSq());
-
// Add the floats
for (rapidjson::SizeType i = 0; i < vert.Size(); i++)
{
vertices.emplace_back(static_cast(vert[i].GetDouble()));
}
}
-
// We were computing length squared earlier
mRadius = Math::Sqrt(mRadius);
-
// Load in the indices
const rapidjson::Value& indJson = doc["indices"];
if (!indJson.IsArray() || indJson.Size() < 1)
@@ -133,7 +114,6 @@ bool Mesh::Load(const std::string& fileName, Renderer* renderer)
SDL_Log("Mesh %s has no indices", fileName.c_str());
return false;
}
-
std::vector indices;
indices.reserve(indJson.Size() * 3);
for (rapidjson::SizeType i = 0; i < indJson.Size(); i++)
@@ -144,22 +124,19 @@ bool Mesh::Load(const std::string& fileName, Renderer* renderer)
SDL_Log("Invalid indices for %s", fileName.c_str());
return false;
}
-
indices.emplace_back(ind[0].GetUint());
indices.emplace_back(ind[1].GetUint());
indices.emplace_back(ind[2].GetUint());
}
-
// Now create a vertex array
- mVertexArray = new VertexArray(vertices.data(), static_cast(vertices.size()) / vertSize,
- indices.data(), static_cast(indices.size()));
+ pVertexArray = new VertexArray(vertices.data(), static_cast(vertices.size()) / vertSize, indices.data(), static_cast(indices.size()));
return true;
}
void Mesh::Unload()
{
- delete mVertexArray;
- mVertexArray = nullptr;
+ delete pVertexArray;
+ pVertexArray = nullptr;
}
Texture* Mesh::GetTexture(size_t index)
@@ -172,4 +149,4 @@ Texture* Mesh::GetTexture(size_t index)
{
return nullptr;
}
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Mesh.h b/Chapter07/Mesh.h
index 3c1b5a3e..471f671b 100644
--- a/Chapter07/Mesh.h
+++ b/Chapter07/Mesh.h
@@ -19,7 +19,7 @@ class Mesh
bool Load(const std::string& fileName, class Renderer* renderer);
void Unload();
// Get the vertex array associated with this mesh
- class VertexArray* GetVertexArray() { return mVertexArray; }
+ class VertexArray* GetVertexArray() { return pVertexArray; }
// Get a texture from specified index
class Texture* GetTexture(size_t index);
// Get name of shader
@@ -32,7 +32,7 @@ class Mesh
// Textures associated with this mesh
std::vector mTextures;
// Vertex array associated with this mesh
- class VertexArray* mVertexArray;
+ class VertexArray* pVertexArray;
// Name of shader specified by mesh
std::string mShaderName;
// Stores object space bounding sphere radius
diff --git a/Chapter07/MeshComponent.cpp b/Chapter07/MeshComponent.cpp
index 1f4cbdb2..9020987d 100644
--- a/Chapter07/MeshComponent.cpp
+++ b/Chapter07/MeshComponent.cpp
@@ -15,38 +15,34 @@
#include "Texture.h"
#include "VertexArray.h"
-MeshComponent::MeshComponent(Actor* owner)
- :Component(owner)
- ,mMesh(nullptr)
- ,mTextureIndex(0)
+MeshComponent::MeshComponent(Actor* owner): Component(owner), pMesh(nullptr), mTextureIndex(0)
{
- mOwner->GetGame()->GetRenderer()->AddMeshComp(this);
+ pOwner->GetGame()->GetRenderer()->AddMeshComp(this);
}
MeshComponent::~MeshComponent()
{
- mOwner->GetGame()->GetRenderer()->RemoveMeshComp(this);
+ pOwner->GetGame()->GetRenderer()->RemoveMeshComp(this);
}
void MeshComponent::Draw(Shader* shader)
{
- if (mMesh)
+ if (pMesh)
{
// Set the world transform
- shader->SetMatrixUniform("uWorldTransform",
- mOwner->GetWorldTransform());
+ shader->SetMatrixUniform("uWorldTransform", pOwner->GetWorldTransform());
// Set specular power
- shader->SetFloatUniform("uSpecPower", mMesh->GetSpecPower());
+ shader->SetFloatUniform("uSpecPower", pMesh->GetSpecPower());
// Set the active texture
- Texture* t = mMesh->GetTexture(mTextureIndex);
+ Texture* t = pMesh->GetTexture(mTextureIndex);
if (t)
{
t->SetActive();
}
// Set the mesh's vertex array as active
- VertexArray* va = mMesh->GetVertexArray();
+ VertexArray* va = pMesh->GetVertexArray();
va->SetActive();
// Draw
glDrawElements(GL_TRIANGLES, va->GetNumIndices(), GL_UNSIGNED_INT, nullptr);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter07/MeshComponent.h b/Chapter07/MeshComponent.h
index 48765568..bda30a84 100644
--- a/Chapter07/MeshComponent.h
+++ b/Chapter07/MeshComponent.h
@@ -10,7 +10,7 @@
#include "Component.h"
#include
-class MeshComponent : public Component
+class MeshComponent: public Component
{
public:
MeshComponent(class Actor* owner);
@@ -18,9 +18,9 @@ class MeshComponent : public Component
// Draw this mesh component
virtual void Draw(class Shader* shader);
// Set the mesh/texture index used by mesh component
- virtual void SetMesh(class Mesh* mesh) { mMesh = mesh; }
+ virtual void SetMesh(class Mesh* mesh) { pMesh = mesh; }
void SetTextureIndex(size_t index) { mTextureIndex = index; }
protected:
- class Mesh* mMesh;
+ class Mesh* pMesh;
size_t mTextureIndex;
-};
+};
\ No newline at end of file
diff --git a/Chapter07/MoveComponent.cpp b/Chapter07/MoveComponent.cpp
index 5b51c6fc..8b96a42c 100644
--- a/Chapter07/MoveComponent.cpp
+++ b/Chapter07/MoveComponent.cpp
@@ -9,32 +9,27 @@
#include "MoveComponent.h"
#include "Actor.h"
-MoveComponent::MoveComponent(class Actor* owner, int updateOrder)
-:Component(owner, updateOrder)
-,mAngularSpeed(0.0f)
-,mForwardSpeed(0.0f)
+MoveComponent::MoveComponent(class Actor* owner, int updateOrder): Component(owner, updateOrder), mAngularSpeed(0.0f), mForwardSpeed(0.0f)
{
-
}
void MoveComponent::Update(float deltaTime)
{
if (!Math::NearZero(mAngularSpeed))
{
- Quaternion rot = mOwner->GetRotation();
+ Quaternion rot = pOwner->GetRotation();
float angle = mAngularSpeed * deltaTime;
// Create quaternion for incremental rotation
// (Rotate about up axis)
Quaternion inc(Vector3::UnitZ, angle);
// Concatenate old and new quaternion
rot = Quaternion::Concatenate(rot, inc);
- mOwner->SetRotation(rot);
+ pOwner->SetRotation(rot);
}
-
if (!Math::NearZero(mForwardSpeed))
{
- Vector3 pos = mOwner->GetPosition();
- pos += mOwner->GetForward() * mForwardSpeed * deltaTime;
- mOwner->SetPosition(pos);
+ Vector3 pos = pOwner->GetPosition();
+ pos += pOwner->GetForward() * mForwardSpeed * deltaTime;
+ pOwner->SetPosition(pos);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter07/MoveComponent.h b/Chapter07/MoveComponent.h
index def7d389..c737e66b 100644
--- a/Chapter07/MoveComponent.h
+++ b/Chapter07/MoveComponent.h
@@ -9,13 +9,12 @@
#pragma once
#include "Component.h"
-class MoveComponent : public Component
+class MoveComponent: public Component
{
public:
// Lower update order to update first
MoveComponent(class Actor* owner, int updateOrder = 10);
void Update(float deltaTime) override;
-
float GetAngularSpeed() const { return mAngularSpeed; }
float GetForwardSpeed() const { return mForwardSpeed; }
void SetAngularSpeed(float speed) { mAngularSpeed = speed; }
@@ -23,4 +22,4 @@ class MoveComponent : public Component
private:
float mAngularSpeed;
float mForwardSpeed;
-};
+};
\ No newline at end of file
diff --git a/Chapter07/PlaneActor.cpp b/Chapter07/PlaneActor.cpp
index 5398ca4c..696a148f 100644
--- a/Chapter07/PlaneActor.cpp
+++ b/Chapter07/PlaneActor.cpp
@@ -11,10 +11,9 @@
#include "Renderer.h"
#include "MeshComponent.h"
-PlaneActor::PlaneActor(Game* game)
- :Actor(game)
+PlaneActor::PlaneActor(Game* game): Actor(game)
{
SetScale(10.0f);
MeshComponent* mc = new MeshComponent(this);
mc->SetMesh(GetGame()->GetRenderer()->GetMesh("Assets/Plane.gpmesh"));
-}
+}
\ No newline at end of file
diff --git a/Chapter07/PlaneActor.h b/Chapter07/PlaneActor.h
index 8187b64a..ca323e87 100644
--- a/Chapter07/PlaneActor.h
+++ b/Chapter07/PlaneActor.h
@@ -9,7 +9,7 @@
#pragma once
#include "Actor.h"
-class PlaneActor : public Actor
+class PlaneActor: public Actor
{
public:
PlaneActor(class Game* game);
diff --git a/Chapter07/Renderer.cpp b/Chapter07/Renderer.cpp
index ed25f3bd..69559451 100644
--- a/Chapter07/Renderer.cpp
+++ b/Chapter07/Renderer.cpp
@@ -16,10 +16,7 @@
#include "MeshComponent.h"
#include
-Renderer::Renderer(Game* game)
- :mGame(game)
- ,mSpriteShader(nullptr)
- ,mMeshShader(nullptr)
+Renderer::Renderer(Game* game): pGame(game), pSpriteShader(nullptr), pMeshShader(nullptr)
{
}
@@ -31,8 +28,7 @@ bool Renderer::Initialize(float screenWidth, float screenHeight)
{
mScreenWidth = screenWidth;
mScreenHeight = screenHeight;
-
- // Set OpenGL attributes
+// Set OpenGL attributes:
// Use the core OpenGL profile
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
// Specify version 3.3
@@ -48,18 +44,14 @@ bool Renderer::Initialize(float screenWidth, float screenHeight)
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// Force OpenGL to use hardware acceleration
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
-
- mWindow = SDL_CreateWindow("Game Programming in C++ (Chapter 7)", 100, 100,
- static_cast(mScreenWidth), static_cast(mScreenHeight), SDL_WINDOW_OPENGL);
- if (!mWindow)
+ pWindow = SDL_CreateWindow("Game Programming in C++ (Chapter 7)", 100, 100, static_cast(mScreenWidth), static_cast(mScreenHeight), SDL_WINDOW_OPENGL);
+ if (!pWindow)
{
SDL_Log("Failed to create window: %s", SDL_GetError());
return false;
}
-
// Create an OpenGL context
- mContext = SDL_GL_CreateContext(mWindow);
-
+ mContext = SDL_GL_CreateContext(pWindow);
// Initialize GLEW
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
@@ -67,33 +59,28 @@ bool Renderer::Initialize(float screenWidth, float screenHeight)
SDL_Log("Failed to initialize GLEW.");
return false;
}
-
- // On some platforms, GLEW will emit a benign error code,
- // so clear it
+ // On some platforms, GLEW will emit a benign error code, so clear it
glGetError();
-
// Make sure we can create/compile shaders
if (!LoadShaders())
{
SDL_Log("Failed to load shaders.");
return false;
}
-
// Create quad for drawing sprites
CreateSpriteVerts();
-
return true;
}
void Renderer::Shutdown()
{
- delete mSpriteVerts;
- mSpriteShader->Unload();
- delete mSpriteShader;
- mMeshShader->Unload();
- delete mMeshShader;
+ delete pSpriteVerts;
+ pSpriteShader->Unload();
+ delete pSpriteShader;
+ pMeshShader->Unload();
+ delete pMeshShader;
SDL_GL_DeleteContext(mContext);
- SDL_DestroyWindow(mWindow);
+ SDL_DestroyWindow(pWindow);
}
void Renderer::UnloadData()
@@ -105,7 +92,6 @@ void Renderer::UnloadData()
delete i.second;
}
mTextures.clear();
-
// Destroy meshes
for (auto i : mMeshes)
{
@@ -117,26 +103,24 @@ void Renderer::UnloadData()
void Renderer::Draw()
{
- // Set the clear color to light grey
+ // Set the clear color to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
// Draw mesh components
// Enable depth buffering/disable alpha blend
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
// Set the mesh shader active
- mMeshShader->SetActive();
+ pMeshShader->SetActive();
// Update view-projection matrix
- mMeshShader->SetMatrixUniform("uViewProj", mView * mProjection);
+ pMeshShader->SetMatrixUniform("uViewProj", mView * mProjection);
// Update lighting uniforms
- SetLightUniforms(mMeshShader);
- for (auto mc : mMeshComps)
+ SetLightUniforms(pMeshShader);
+ for (auto mc: mMeshComps)
{
- mc->Draw(mMeshShader);
+ mc->Draw(pMeshShader);
}
-
// Draw all sprite components
// Disable depth buffering
glDisable(GL_DEPTH_TEST);
@@ -144,35 +128,29 @@ void Renderer::Draw()
glEnable(GL_BLEND);
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
-
- // Set shader/vao as active
- mSpriteShader->SetActive();
- mSpriteVerts->SetActive();
- for (auto sprite : mSprites)
+ // Set shader/VAO as active
+ pSpriteShader->SetActive();
+ pSpriteVerts->SetActive();
+ for (auto sprite: mSprites)
{
- sprite->Draw(mSpriteShader);
+ sprite->Draw(pSpriteShader);
}
-
// Swap the buffers
- SDL_GL_SwapWindow(mWindow);
+ SDL_GL_SwapWindow(pWindow);
}
void Renderer::AddSprite(SpriteComponent* sprite)
{
- // Find the insertion point in the sorted vector
- // (The first element with a higher draw order than me)
+ // Find the insertion point in the sorted vector (The first element with a higher draw order than me)
int myDrawOrder = sprite->GetDrawOrder();
auto iter = mSprites.begin();
- for (;
- iter != mSprites.end();
- ++iter)
+ for (; iter != mSprites.end(); ++iter)
{
if (myDrawOrder < (*iter)->GetDrawOrder())
{
break;
}
}
-
// Inserts element before position of iterator
mSprites.insert(iter, sprite);
}
@@ -245,30 +223,26 @@ Mesh* Renderer::GetMesh(const std::string & fileName)
bool Renderer::LoadShaders()
{
// Create sprite shader
- mSpriteShader = new Shader();
- if (!mSpriteShader->Load("Shaders/Sprite.vert", "Shaders/Sprite.frag"))
+ pSpriteShader = new Shader();
+ if (!pSpriteShader->Load("Shaders/Sprite.vert", "Shaders/Sprite.frag"))
{
return false;
}
-
- mSpriteShader->SetActive();
+ pSpriteShader->SetActive();
// Set the view-projection matrix
Matrix4 viewProj = Matrix4::CreateSimpleViewProj(mScreenWidth, mScreenHeight);
- mSpriteShader->SetMatrixUniform("uViewProj", viewProj);
-
+ pSpriteShader->SetMatrixUniform("uViewProj", viewProj);
// Create basic mesh shader
- mMeshShader = new Shader();
- if (!mMeshShader->Load("Shaders/Phong.vert", "Shaders/Phong.frag"))
+ pMeshShader = new Shader();
+ if (!pMeshShader->Load("Shaders/Phong.vert", "Shaders/Phong.frag"))
{
return false;
}
-
- mMeshShader->SetActive();
+ pMeshShader->SetActive();
// Set the view-projection matrix
mView = Matrix4::CreateLookAt(Vector3::Zero, Vector3::UnitX, Vector3::UnitZ);
- mProjection = Matrix4::CreatePerspectiveFOV(Math::ToRadians(70.0f),
- mScreenWidth, mScreenHeight, 25.0f, 10000.0f);
- mMeshShader->SetMatrixUniform("uViewProj", mView * mProjection);
+ mProjection = Matrix4::CreatePerspectiveFOV(Math::ToRadians(70.0f), mScreenWidth, mScreenHeight, 25.0f, 10000.0f);
+ pMeshShader->SetMatrixUniform("uViewProj", mView * mProjection);
return true;
}
@@ -280,13 +254,11 @@ void Renderer::CreateSpriteVerts()
0.5f,-0.5f, 0.f, 0.f, 0.f, 0.0f, 1.f, 1.f, // bottom right
-0.5f,-0.5f, 0.f, 0.f, 0.f, 0.0f, 0.f, 1.f // bottom left
};
-
unsigned int indices[] = {
0, 1, 2,
2, 3, 0
};
-
- mSpriteVerts = new VertexArray(vertices, 4, indices, 6);
+ pSpriteVerts = new VertexArray(vertices, 4, indices, 6);
}
void Renderer::SetLightUniforms(Shader* shader)
@@ -298,10 +270,7 @@ void Renderer::SetLightUniforms(Shader* shader)
// Ambient light
shader->SetVectorUniform("uAmbientLight", mAmbientLight);
// Directional light
- shader->SetVectorUniform("uDirLight.mDirection",
- mDirLight.mDirection);
- shader->SetVectorUniform("uDirLight.mDiffuseColor",
- mDirLight.mDiffuseColor);
- shader->SetVectorUniform("uDirLight.mSpecColor",
- mDirLight.mSpecColor);
-}
+ shader->SetVectorUniform("uDirLight.mDirection", mDirLight.mDirection);
+ shader->SetVectorUniform("uDirLight.mDiffuseColor", mDirLight.mDiffuseColor);
+ shader->SetVectorUniform("uDirLight.mSpecColor", mDirLight.mSpecColor);
+}
\ No newline at end of file
diff --git a/Chapter07/Renderer.h b/Chapter07/Renderer.h
index 12746df2..9f04270a 100644
--- a/Chapter07/Renderer.h
+++ b/Chapter07/Renderer.h
@@ -28,69 +28,52 @@ class Renderer
public:
Renderer(class Game* game);
~Renderer();
-
bool Initialize(float screenWidth, float screenHeight);
void Shutdown();
void UnloadData();
-
void Draw();
-
void AddSprite(class SpriteComponent* sprite);
void RemoveSprite(class SpriteComponent* sprite);
-
void AddMeshComp(class MeshComponent* mesh);
void RemoveMeshComp(class MeshComponent* mesh);
-
class Texture* GetTexture(const std::string& fileName);
class Mesh* GetMesh(const std::string& fileName);
-
void SetViewMatrix(const Matrix4& view) { mView = view; }
-
void SetAmbientLight(const Vector3& ambient) { mAmbientLight = ambient; }
DirectionalLight& GetDirectionalLight() { return mDirLight; }
-
float GetScreenWidth() const { return mScreenWidth; }
float GetScreenHeight() const { return mScreenHeight; }
private:
bool LoadShaders();
void CreateSpriteVerts();
void SetLightUniforms(class Shader* shader);
-
// Map of textures loaded
std::unordered_map mTextures;
// Map of meshes loaded
std::unordered_map mMeshes;
-
// All the sprite components drawn
std::vector mSprites;
-
// All mesh components drawn
std::vector mMeshComps;
-
// Game
- class Game* mGame;
-
+ class Game* pGame;
// Sprite shader
- class Shader* mSpriteShader;
+ class Shader* pSpriteShader;
// Sprite vertex array
- class VertexArray* mSpriteVerts;
-
+ class VertexArray* pSpriteVerts;
// Mesh shader
- class Shader* mMeshShader;
-
+ class Shader* pMeshShader;
// View/projection for 3D shaders
Matrix4 mView;
Matrix4 mProjection;
// Width/height of screen
float mScreenWidth;
float mScreenHeight;
-
// Lighting data
Vector3 mAmbientLight;
DirectionalLight mDirLight;
-
// Window
- SDL_Window* mWindow;
+ SDL_Window* pWindow;
// OpenGL context
SDL_GLContext mContext;
};
\ No newline at end of file
diff --git a/Chapter07/Shader.cpp b/Chapter07/Shader.cpp
index cae3ac07..2bc5f415 100644
--- a/Chapter07/Shader.cpp
+++ b/Chapter07/Shader.cpp
@@ -12,45 +12,31 @@
#include
#include
-Shader::Shader()
- : mShaderProgram(0)
- , mVertexShader(0)
- , mFragShader(0)
+Shader::Shader(): mShaderProgram(0), mVertexShader(0), mFragShader(0)
{
-
}
Shader::~Shader()
{
-
}
bool Shader::Load(const std::string& vertName, const std::string& fragName)
{
// Compile vertex and pixel shaders
- if (!CompileShader(vertName,
- GL_VERTEX_SHADER,
- mVertexShader) ||
- !CompileShader(fragName,
- GL_FRAGMENT_SHADER,
- mFragShader))
+ if (!CompileShader(vertName, GL_VERTEX_SHADER, mVertexShader) || !CompileShader(fragName, GL_FRAGMENT_SHADER, mFragShader))
{
return false;
}
-
- // Now create a shader program that
- // links together the vertex/frag shaders
+ // Now create a shader program that links together the vertex/frag shaders
mShaderProgram = glCreateProgram();
glAttachShader(mShaderProgram, mVertexShader);
glAttachShader(mShaderProgram, mFragShader);
glLinkProgram(mShaderProgram);
-
// Verify that the program linked successfully
if (!IsValidProgram())
{
return false;
}
-
return true;
}
@@ -90,9 +76,7 @@ void Shader::SetFloatUniform(const char* name, float value)
glUniform1f(loc, value);
}
-bool Shader::CompileShader(const std::string& fileName,
- GLenum shaderType,
- GLuint& outShader)
+bool Shader::CompileShader(const std::string& fileName, GLenum shaderType, GLuint& outShader)
{
// Open file
std::ifstream shaderFile(fileName);
@@ -103,13 +87,11 @@ bool Shader::CompileShader(const std::string& fileName,
sstream << shaderFile.rdbuf();
std::string contents = sstream.str();
const char* contentsChar = contents.c_str();
-
// Create a shader of the specified type
outShader = glCreateShader(shaderType);
// Set the source characters and try to compile
glShaderSource(outShader, 1, &(contentsChar), nullptr);
glCompileShader(outShader);
-
if (!IsCompiled(outShader))
{
SDL_Log("Failed to compile shader %s", fileName.c_str());
@@ -121,7 +103,6 @@ bool Shader::CompileShader(const std::string& fileName,
SDL_Log("Shader file not found: %s", fileName.c_str());
return false;
}
-
return true;
}
@@ -130,7 +111,6 @@ bool Shader::IsCompiled(GLuint shader)
GLint status;
// Query the compile status
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
-
if (status != GL_TRUE)
{
char buffer[512];
@@ -139,13 +119,11 @@ bool Shader::IsCompiled(GLuint shader)
SDL_Log("GLSL Compile Failed:\n%s", buffer);
return false;
}
-
return true;
}
bool Shader::IsValidProgram()
{
-
GLint status;
// Query the link status
glGetProgramiv(mShaderProgram, GL_LINK_STATUS, &status);
@@ -157,6 +135,5 @@ bool Shader::IsValidProgram()
SDL_Log("GLSL Link Status:\n%s", buffer);
return false;
}
-
return true;
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Shader.h b/Chapter07/Shader.h
index 929c9e41..f9c5e33e 100644
--- a/Chapter07/Shader.h
+++ b/Chapter07/Shader.h
@@ -29,10 +29,7 @@ class Shader
void SetFloatUniform(const char* name, float value);
private:
// Tries to compile the specified shader
- bool CompileShader(const std::string& fileName,
- GLenum shaderType,
- GLuint& outShader);
-
+ bool CompileShader(const std::string& fileName, GLenum shaderType, GLuint& outShader);
// Tests whether shader compiled successfully
bool IsCompiled(GLuint shader);
// Tests whether vertex/fragment programs link
@@ -42,4 +39,4 @@ class Shader
GLuint mVertexShader;
GLuint mFragShader;
GLuint mShaderProgram;
-};
+};
\ No newline at end of file
diff --git a/Chapter07/Shaders/BasicMesh.frag b/Chapter07/Shaders/BasicMesh.frag
index 481a669a..54f0924f 100644
--- a/Chapter07/Shaders/BasicMesh.frag
+++ b/Chapter07/Shaders/BasicMesh.frag
@@ -11,10 +11,8 @@
// Tex coord input from vertex shader
in vec2 fragTexCoord;
-
// This corresponds to the output color to the color buffer
out vec4 outColor;
-
// This is used for the texture sampling
uniform sampler2D uTexture;
@@ -22,4 +20,4 @@ void main()
{
// Sample color from texture
outColor = texture(uTexture, fragTexCoord);
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Shaders/BasicMesh.vert b/Chapter07/Shaders/BasicMesh.vert
index 7d21ad0d..297d197b 100644
--- a/Chapter07/Shaders/BasicMesh.vert
+++ b/Chapter07/Shaders/BasicMesh.vert
@@ -12,12 +12,10 @@
// Uniforms for world transform and view-proj
uniform mat4 uWorldTransform;
uniform mat4 uViewProj;
-
// Attribute 0 is position, 1 is normal, 2 is tex coords.
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inTexCoord;
-
// Any vertex outputs (other than position)
out vec2 fragTexCoord;
@@ -27,7 +25,6 @@ void main()
vec4 pos = vec4(inPosition, 1.0);
// Transform to position world space, then clip space
gl_Position = pos * uWorldTransform * uViewProj;
-
// Pass along the texture coordinate to frag shader
fragTexCoord = inTexCoord;
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Shaders/Phong.frag b/Chapter07/Shaders/Phong.frag
index 7bb2678c..081fa77e 100644
--- a/Chapter07/Shaders/Phong.frag
+++ b/Chapter07/Shaders/Phong.frag
@@ -16,13 +16,10 @@ in vec2 fragTexCoord;
in vec3 fragNormal;
// Position (in world space)
in vec3 fragWorldPos;
-
// This corresponds to the output color to the color buffer
out vec4 outColor;
-
// This is used for the texture sampling
uniform sampler2D uTexture;
-
// Create a struct for directional light
struct DirectionalLight
{
@@ -33,7 +30,6 @@ struct DirectionalLight
// Specular color
vec3 mSpecColor;
};
-
// Uniforms for lighting
// Camera position (in world space)
uniform vec3 uCameraPos;
@@ -41,7 +37,6 @@ uniform vec3 uCameraPos;
uniform float uSpecPower;
// Ambient light level
uniform vec3 uAmbientLight;
-
// Directional Light
uniform DirectionalLight uDirLight;
@@ -55,7 +50,6 @@ void main()
vec3 V = normalize(uCameraPos - fragWorldPos);
// Reflection of -L about N
vec3 R = normalize(reflect(-L, N));
-
// Compute phong reflection
vec3 Phong = uAmbientLight;
float NdotL = dot(N, L);
@@ -65,7 +59,6 @@ void main()
vec3 Specular = uDirLight.mSpecColor * pow(max(0.0, dot(R, V)), uSpecPower);
Phong += Diffuse + Specular;
}
-
// Final color is texture color times phong light (alpha = 1)
outColor = texture(uTexture, fragTexCoord) * vec4(Phong, 1.0f);
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Shaders/Phong.vert b/Chapter07/Shaders/Phong.vert
index af5078dc..cfa49a2b 100644
--- a/Chapter07/Shaders/Phong.vert
+++ b/Chapter07/Shaders/Phong.vert
@@ -12,12 +12,10 @@
// Uniforms for world transform and view-proj
uniform mat4 uWorldTransform;
uniform mat4 uViewProj;
-
// Attribute 0 is position, 1 is normal, 2 is tex coords.
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inTexCoord;
-
// Any vertex outputs (other than position)
out vec2 fragTexCoord;
// Normal (in world space)
@@ -35,10 +33,8 @@ void main()
fragWorldPos = pos.xyz;
// Transform to clip space
gl_Position = pos * uViewProj;
-
// Transform normal into world space (w = 0)
fragNormal = (vec4(inNormal, 0.0f) * uWorldTransform).xyz;
-
// Pass along the texture coordinate to frag shader
fragTexCoord = inTexCoord;
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Shaders/Sprite.frag b/Chapter07/Shaders/Sprite.frag
index 481a669a..54f0924f 100644
--- a/Chapter07/Shaders/Sprite.frag
+++ b/Chapter07/Shaders/Sprite.frag
@@ -11,10 +11,8 @@
// Tex coord input from vertex shader
in vec2 fragTexCoord;
-
// This corresponds to the output color to the color buffer
out vec4 outColor;
-
// This is used for the texture sampling
uniform sampler2D uTexture;
@@ -22,4 +20,4 @@ void main()
{
// Sample color from texture
outColor = texture(uTexture, fragTexCoord);
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Shaders/Sprite.vert b/Chapter07/Shaders/Sprite.vert
index 7d21ad0d..297d197b 100644
--- a/Chapter07/Shaders/Sprite.vert
+++ b/Chapter07/Shaders/Sprite.vert
@@ -12,12 +12,10 @@
// Uniforms for world transform and view-proj
uniform mat4 uWorldTransform;
uniform mat4 uViewProj;
-
// Attribute 0 is position, 1 is normal, 2 is tex coords.
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inTexCoord;
-
// Any vertex outputs (other than position)
out vec2 fragTexCoord;
@@ -27,7 +25,6 @@ void main()
vec4 pos = vec4(inPosition, 1.0);
// Transform to position world space, then clip space
gl_Position = pos * uWorldTransform * uViewProj;
-
// Pass along the texture coordinate to frag shader
fragTexCoord = inTexCoord;
-}
+}
\ No newline at end of file
diff --git a/Chapter07/SoundEvent.cpp b/Chapter07/SoundEvent.cpp
index 6edbda39..2feaa07c 100644
--- a/Chapter07/SoundEvent.cpp
+++ b/Chapter07/SoundEvent.cpp
@@ -10,26 +10,22 @@
#include "AudioSystem.h"
#include
-SoundEvent::SoundEvent(class AudioSystem* system, unsigned int id)
- :mSystem(system)
- ,mID(id)
+SoundEvent::SoundEvent(class AudioSystem* system, unsigned int id): pSystem(system), mID(id)
{
}
-SoundEvent::SoundEvent()
- :mSystem(nullptr)
- ,mID(0)
+SoundEvent::SoundEvent(): pSystem(nullptr), mID(0)
{
}
bool SoundEvent::IsValid()
{
- return (mSystem && mSystem->GetEventInstance(mID) != nullptr);
+ return (pSystem && pSystem->GetEventInstance(mID) != nullptr);
}
void SoundEvent::Restart()
{
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
event->start();
@@ -38,19 +34,17 @@ void SoundEvent::Restart()
void SoundEvent::Stop(bool allowFadeOut /* true */)
{
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
- FMOD_STUDIO_STOP_MODE mode = allowFadeOut ?
- FMOD_STUDIO_STOP_ALLOWFADEOUT :
- FMOD_STUDIO_STOP_IMMEDIATE;
+ FMOD_STUDIO_STOP_MODE mode = allowFadeOut ? FMOD_STUDIO_STOP_ALLOWFADEOUT : FMOD_STUDIO_STOP_IMMEDIATE;
event->stop(mode);
}
}
void SoundEvent::SetPaused(bool pause)
{
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
event->setPaused(pause);
@@ -59,7 +53,7 @@ void SoundEvent::SetPaused(bool pause)
void SoundEvent::SetVolume(float value)
{
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
event->setVolume(value);
@@ -68,7 +62,7 @@ void SoundEvent::SetVolume(float value)
void SoundEvent::SetPitch(float value)
{
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
event->setPitch(value);
@@ -77,17 +71,17 @@ void SoundEvent::SetPitch(float value)
void SoundEvent::SetParameter(const std::string& name, float value)
{
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
- event->setParameterValue(name.c_str(), value);
+ event->setParameterByName(name.c_str(), value);
}
}
bool SoundEvent::GetPaused() const
{
bool retVal = false;
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
event->getPaused(&retVal);
@@ -98,7 +92,7 @@ bool SoundEvent::GetPaused() const
float SoundEvent::GetVolume() const
{
float retVal = 0.0f;
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
event->getVolume(&retVal);
@@ -109,7 +103,7 @@ float SoundEvent::GetVolume() const
float SoundEvent::GetPitch() const
{
float retVal = 0.0f;
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
event->getPitch(&retVal);
@@ -120,10 +114,10 @@ float SoundEvent::GetPitch() const
float SoundEvent::GetParameter(const std::string& name)
{
float retVal = 0.0f;
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
- event->getParameterValue(name.c_str(), &retVal);
+ event->getParameterByName(name.c_str(), &retVal);
}
return retVal;
}
@@ -131,7 +125,7 @@ float SoundEvent::GetParameter(const std::string& name)
bool SoundEvent::Is3D() const
{
bool retVal = false;
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
// Get the event description
@@ -159,9 +153,9 @@ namespace
}
}
-void SoundEvent::Set3DAttributes(const Matrix4& worldTrans)
+void SoundEvent::Set3DAttributes(const Matrix4& worldTrans, const Vector3& velocity)
{
- auto event = mSystem ? mSystem->GetEventInstance(mID) : nullptr;
+ auto event = pSystem ? pSystem->GetEventInstance(mID) : nullptr;
if (event)
{
FMOD_3D_ATTRIBUTES attr;
@@ -171,8 +165,8 @@ void SoundEvent::Set3DAttributes(const Matrix4& worldTrans)
attr.forward = VecToFMOD(worldTrans.GetXAxis());
// Third row is up
attr.up = VecToFMOD(worldTrans.GetZAxis());
- // Set velocity to zero (fix if using Doppler effect)
- attr.velocity = { 0.0f, 0.0f, 0.0f };
+ // Set velocity
+ attr.velocity = VecToFMOD(velocity);
event->set3DAttributes(&attr);
}
-}
+}
\ No newline at end of file
diff --git a/Chapter07/SoundEvent.h b/Chapter07/SoundEvent.h
index ae78ac8a..7391c738 100644
--- a/Chapter07/SoundEvent.h
+++ b/Chapter07/SoundEvent.h
@@ -32,13 +32,13 @@ class SoundEvent
float GetParameter(const std::string& name);
// Positional
bool Is3D() const;
- void Set3DAttributes(const Matrix4& worldTrans);
+ void Set3DAttributes(const Matrix4& worldTrans, const Vector3& velocity = Vector3::Zero);
protected:
// Make this constructor protected and AudioSystem a friend
// so that only AudioSystem can access this constructor.
friend class AudioSystem;
SoundEvent(class AudioSystem* system, unsigned int id);
private:
- class AudioSystem* mSystem;
+ class AudioSystem* pSystem;
unsigned int mID;
};
\ No newline at end of file
diff --git a/Chapter07/SpriteComponent.cpp b/Chapter07/SpriteComponent.cpp
index eb7b77aa..1708f4d6 100644
--- a/Chapter07/SpriteComponent.cpp
+++ b/Chapter07/SpriteComponent.cpp
@@ -13,40 +13,28 @@
#include "Game.h"
#include "Renderer.h"
-SpriteComponent::SpriteComponent(Actor* owner, int drawOrder)
- :Component(owner)
- ,mTexture(nullptr)
- ,mDrawOrder(drawOrder)
- ,mTexWidth(0)
- ,mTexHeight(0)
+SpriteComponent::SpriteComponent(Actor* owner, int drawOrder): Component(owner), pTexture(nullptr), mDrawOrder(drawOrder), mTexWidth(0), mTexHeight(0)
{
- mOwner->GetGame()->GetRenderer()->AddSprite(this);
+ pOwner->GetGame()->GetRenderer()->AddSprite(this);
}
SpriteComponent::~SpriteComponent()
{
- mOwner->GetGame()->GetRenderer()->RemoveSprite(this);
+ pOwner->GetGame()->GetRenderer()->RemoveSprite(this);
}
void SpriteComponent::Draw(Shader* shader)
{
- if (mTexture)
+ if (pTexture)
{
// Scale the quad by the width/height of texture
- Matrix4 scaleMat = Matrix4::CreateScale(
- static_cast(mTexWidth),
- static_cast(mTexHeight),
- 1.0f);
-
- Matrix4 world = scaleMat * mOwner->GetWorldTransform();
-
- // Since all sprites use the same shader/vertices,
- // the game first sets them active before any sprite draws
-
+ Matrix4 scaleMat = Matrix4::CreateScale( static_cast(mTexWidth), static_cast(mTexHeight), 1.0f);
+ Matrix4 world = scaleMat * pOwner->GetWorldTransform();
+ // Since all sprites use the same shader/vertices, the game first sets them active before any sprite draws
// Set world transform
shader->SetMatrixUniform("uWorldTransform", world);
// Set current texture
- mTexture->SetActive();
+ pTexture->SetActive();
// Draw quad
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
}
@@ -54,8 +42,8 @@ void SpriteComponent::Draw(Shader* shader)
void SpriteComponent::SetTexture(Texture* texture)
{
- mTexture = texture;
+ pTexture = texture;
// Set width/height
mTexWidth = texture->GetWidth();
mTexHeight = texture->GetHeight();
-}
+}
\ No newline at end of file
diff --git a/Chapter07/SpriteComponent.h b/Chapter07/SpriteComponent.h
index 6c5642f2..581cb883 100644
--- a/Chapter07/SpriteComponent.h
+++ b/Chapter07/SpriteComponent.h
@@ -9,22 +9,20 @@
#pragma once
#include "Component.h"
#include "SDL/SDL.h"
-class SpriteComponent : public Component
+class SpriteComponent: public Component
{
public:
// (Lower draw order corresponds with further back)
SpriteComponent(class Actor* owner, int drawOrder = 100);
~SpriteComponent();
-
virtual void Draw(class Shader* shader);
virtual void SetTexture(class Texture* texture);
-
int GetDrawOrder() const { return mDrawOrder; }
int GetTexHeight() const { return mTexHeight; }
int GetTexWidth() const { return mTexWidth; }
protected:
- class Texture* mTexture;
+ class Texture* pTexture;
int mDrawOrder;
int mTexWidth;
int mTexHeight;
-};
+};
\ No newline at end of file
diff --git a/Chapter07/Texture.cpp b/Chapter07/Texture.cpp
index ddde35f0..a2c632c9 100644
--- a/Chapter07/Texture.cpp
+++ b/Chapter07/Texture.cpp
@@ -11,50 +11,35 @@
#include
#include
-Texture::Texture()
-:mTextureID(0)
-,mWidth(0)
-,mHeight(0)
+Texture::Texture(): mTextureID(0), mWidth(0), mHeight(0)
{
-
}
Texture::~Texture()
{
-
}
bool Texture::Load(const std::string& fileName)
{
int channels = 0;
-
- unsigned char* image = SOIL_load_image(fileName.c_str(),
- &mWidth, &mHeight, &channels, SOIL_LOAD_AUTO);
-
+ unsigned char* image = SOIL_load_image(fileName.c_str(), &mWidth, &mHeight, &channels, SOIL_LOAD_AUTO);
if (image == nullptr)
{
SDL_Log("SOIL failed to load image %s: %s", fileName.c_str(), SOIL_last_result());
return false;
}
-
int format = GL_RGB;
if (channels == 4)
{
format = GL_RGBA;
}
-
glGenTextures(1, &mTextureID);
glBindTexture(GL_TEXTURE_2D, mTextureID);
-
- glTexImage2D(GL_TEXTURE_2D, 0, format, mWidth, mHeight, 0, format,
- GL_UNSIGNED_BYTE, image);
-
+ glTexImage2D(GL_TEXTURE_2D, 0, format, mWidth, mHeight, 0, format, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
-
// Enable linear filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
return true;
}
@@ -66,4 +51,4 @@ void Texture::Unload()
void Texture::SetActive()
{
glBindTexture(GL_TEXTURE_2D, mTextureID);
-}
+}
\ No newline at end of file
diff --git a/Chapter07/Texture.h b/Chapter07/Texture.h
index 6c8892fd..b2059450 100644
--- a/Chapter07/Texture.h
+++ b/Chapter07/Texture.h
@@ -13,16 +13,13 @@ class Texture
public:
Texture();
~Texture();
-
bool Load(const std::string& fileName);
void Unload();
-
void SetActive();
-
int GetWidth() const { return mWidth; }
int GetHeight() const { return mHeight; }
private:
unsigned int mTextureID;
int mWidth;
int mHeight;
-};
+};
\ No newline at end of file
diff --git a/Chapter07/VertexArray.cpp b/Chapter07/VertexArray.cpp
index faddcf6c..e97c3bdd 100644
--- a/Chapter07/VertexArray.cpp
+++ b/Chapter07/VertexArray.cpp
@@ -9,25 +9,19 @@
#include "VertexArray.h"
#include
-VertexArray::VertexArray(const float* verts, unsigned int numVerts,
- const unsigned int* indices, unsigned int numIndices)
- :mNumVerts(numVerts)
- ,mNumIndices(numIndices)
+VertexArray::VertexArray(const float* verts, unsigned int numVerts, const unsigned int* indices, unsigned int numIndices): mNumVerts(numVerts), mNumIndices(numIndices)
{
// Create vertex array
glGenVertexArrays(1, &mVertexArray);
glBindVertexArray(mVertexArray);
-
// Create vertex buffer
glGenBuffers(1, &mVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, numVerts * 8 * sizeof(float), verts, GL_STATIC_DRAW);
-
// Create index buffer
glGenBuffers(1, &mIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(unsigned int), indices, GL_STATIC_DRAW);
-
// Specify the vertex attributes
// (For now, assume one vertex format)
// Position is 3 floats
@@ -35,12 +29,10 @@ VertexArray::VertexArray(const float* verts, unsigned int numVerts,
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), 0);
// Normal is 3 floats
glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float),
- reinterpret_cast(sizeof(float) * 3));
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), reinterpret_cast(sizeof(float) * 3));
// Texture coordinates is 2 floats
glEnableVertexAttribArray(2);
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float),
- reinterpret_cast(sizeof(float) * 6));
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), reinterpret_cast(sizeof(float) * 6));
}
VertexArray::~VertexArray()
@@ -53,4 +45,4 @@ VertexArray::~VertexArray()
void VertexArray::SetActive()
{
glBindVertexArray(mVertexArray);
-}
+}
\ No newline at end of file
diff --git a/Chapter07/VertexArray.h b/Chapter07/VertexArray.h
index 5deddc4d..480a254b 100644
--- a/Chapter07/VertexArray.h
+++ b/Chapter07/VertexArray.h
@@ -10,10 +10,8 @@
class VertexArray
{
public:
- VertexArray(const float* verts, unsigned int numVerts,
- const unsigned int* indices, unsigned int numIndices);
+ VertexArray(const float* verts, unsigned int numVerts, const unsigned int* indices, unsigned int numIndices);
~VertexArray();
-
void SetActive();
unsigned int GetNumIndices() const { return mNumIndices; }
unsigned int GetNumVerts() const { return mNumVerts; }
diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 00000000..635d3a14
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,35 @@
+TODO:
+7.2 - Virtual positions for events
+8.1 - Controller support
+8.2 - Abstract input mapping
+9.1 - User controlled camera rotation
+9.2 - Modified spline camera
+10.1 - Add jumping
+10.2 - SweepAndPrune() all 3 axes
+10.3 - Intersect OBB and OBB
+11.1 - Add Main Menu
+11.2 - Better radar
+11.3 - Radar arrow target
+12.1 - Animated bone positions
+12.2 - Blending animations
+13.1 - Add specular component to lights
+13.2 - Add spot lights
+14.1 - Only save changes
+14.2 - Create binary for animations
+Skipped:
+1.1 - I do not care about Pong
+1.2 - I do not care about Pong
+2.1 - Theory stuff
+2.2 - 2D stuff
+2.3 - 2D stuff
+3.1 - Theory stuff
+3.2 - 2D stuff
+3.3 - 2D stuff
+4.2 - I do not care about Connect 4
+Done:
+4.1 - State Machine
+5.1 - Updating exercise
+5.2 - Add vertex color (RGB) to sprite shader
+6.1 - Multiple mesh shaders
+6.2 - Point lights
+7.1 - Add velocity to the listener
\ No newline at end of file