diff --git a/include/happy_bird/controller_utility/character.h b/include/happy_bird/controller_utility/character.h index 5cb72a2..d4a1e3e 100644 --- a/include/happy_bird/controller_utility/character.h +++ b/include/happy_bird/controller_utility/character.h @@ -1,18 +1,30 @@ #pragma once +#include + #include "bullet_common.h" #include "object.h" +#include "color.h" +#include "timer.h" class World; class Character { protected: static float static_pace_; - float max_speed_; - Object* object_; World* world_; + Object* object_; + // Config + float max_speed_ = 15; + float laser_attack_freq_ = 1; + float laser_attack_dist_ = 10; + Color laser_attack_color_ = color::Blue(); + float box_attack_freq_ = 3; + float box_attack_dist_ = 5; + float box_attack_range_ = 5; // along depth axis + Color box_attack_color_ = color::Red(); public: - Character(World*, Object*, float speed = 15); + Character(World*, Object*); ~Character(); void Bind(Object* object); Object* GetDelegate(void); @@ -23,4 +35,6 @@ class Character { void ResetRotate(void); void LaserAttack(void); void BoxAttack(void); -}; + void Gain(float); + void Lose(float); +}; \ No newline at end of file diff --git a/include/happy_bird/particle.h b/include/happy_bird/particle.h index 9667e66..0fb49cf 100644 --- a/include/happy_bird/particle.h +++ b/include/happy_bird/particle.h @@ -66,8 +66,8 @@ enum ParticleFlag{ kRandomColorParticle = 0x60, // 00 for mono // origin var kJitterParticle = 0x80, - // inner force - kInnerParticle = 0x100 + // Special effect + kMockFlame = 0x100 } ; struct ParticleConfig{ // explicit assigned @@ -88,7 +88,7 @@ struct ParticleConfig{ bool gradual; // true for gradual change // external option bool jitter; - bool inner_force; + bool mock_flame; ParticleConfig(glm::vec3 v, Color color, int flags = 0); }; diff --git a/include/happy_bird/stage.h b/include/happy_bird/stage.h index 0040d20..3564c11 100644 --- a/include/happy_bird/stage.h +++ b/include/happy_bird/stage.h @@ -19,7 +19,9 @@ class Stage{ friend Stage; std::shared_ptr data_ref_; public: + StageWrapper(std::shared_ptr shared): data_ref_(shared){ } StageWrapper(Object* naked): data_ref_(naked){ } + ~StageWrapper(){ } std::weak_ptr get(void){ return static_cast >(data_ref_); } diff --git a/include/happy_bird/temp_collection.h b/include/happy_bird/temp_collection.h index 48fe541..00b2279 100644 --- a/include/happy_bird/temp_collection.h +++ b/include/happy_bird/temp_collection.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -16,6 +17,10 @@ class TempCollection{ TempWrapper(Object* naked, float duration):data_ref_(naked), duration_(duration){ timer_ = Timer::New(); } + TempWrapper(std::shared_ptr shared, float duration):data_ref_(shared), duration_(duration){ + timer_ = Timer::New(); + } + ~TempWrapper(){ } std::weak_ptr get(void){ return static_cast >(data_ref_); } @@ -33,6 +38,7 @@ class TempCollection{ } void Update(void); void PushBack(Object* object, float duration); // second + void PushBack(std::shared_ptr object, float duration); private: World* world_; ObjectContainer objects_; diff --git a/include/happy_bird/world.h b/include/happy_bird/world.h index 953b4ff..0d2efce 100644 --- a/include/happy_bird/world.h +++ b/include/happy_bird/world.h @@ -44,6 +44,7 @@ class World{ TempCollection temp_; public: // shared + static bool exit; static int height, width; static Camera* camera; static glm::vec3 global_ambient; diff --git a/resources/hero.png b/resources/hero.png index 41d36a5..95b1772 100644 Binary files a/resources/hero.png and b/resources/hero.png differ diff --git a/resources/hero_0.png b/resources/hero_0.png new file mode 100644 index 0000000..41d36a5 Binary files /dev/null and b/resources/hero_0.png differ diff --git a/resources/vampire.png b/resources/vampire.png new file mode 100644 index 0000000..95b1772 Binary files /dev/null and b/resources/vampire.png differ diff --git a/shader/blood_decr.frag b/shader/blood_decr.frag new file mode 100644 index 0000000..3cf2d50 --- /dev/null +++ b/shader/blood_decr.frag @@ -0,0 +1,22 @@ +#version 330 core + +uniform vec3 uColor; + +in vec3 vColor; +out vec4 FragColor; + +void main(){ + // Halo shading // + vec2 radiant = gl_PointCoord - vec2(0.5, 0.5); + float radiusSquare = dot(radiant, radiant); + if(abs(radiant.y) < 0.1 && abs(radiant.x) < 0.2){ + FragColor = vec4(vColor, 1.0); + } + else if(radiusSquare < 0.15){ // from 0.0625 to 0.25 + FragColor = vec4(vColor, 0.15 - radiusSquare); + } + else{ + discard; + } + // FragColor = vec4(vColor, 1.0); +} \ No newline at end of file diff --git a/shader/blood_incr.frag b/shader/blood_incr.frag index 06db981..d73348c 100644 --- a/shader/blood_incr.frag +++ b/shader/blood_incr.frag @@ -2,6 +2,7 @@ uniform vec3 uColor; +in vec3 vColor; out vec4 FragColor; void main(){ @@ -9,13 +10,13 @@ void main(){ vec2 radiant = gl_PointCoord - vec2(0.5, 0.5); float radiusSquare = dot(radiant, radiant); if(abs(radiant.x) < 0.07 && abs(radiant.y) < 0.2 || abs(radiant.y) < 0.07 && abs(radiant.x) < 0.2){ - FragColor = vec4(uColor, 1.0); + FragColor = vec4(vColor, 1.0); } else if(radiusSquare < 0.25){ // from 0.0625 to 0.25 - FragColor = vec4(uColor, 0.25 - radiusSquare); + FragColor = vec4(vColor, 0.25 - radiusSquare); } else{ discard; } - // FragColor = vec4(uColor, 1.0); + // FragColor = vec4(vColor, 1.0); } \ No newline at end of file diff --git a/shader/common.frag b/shader/common.frag index cf6c8e6..2ef1928 100644 --- a/shader/common.frag +++ b/shader/common.frag @@ -2,32 +2,6 @@ const float zero = 0.00000001; -#define UnfoldParallelSingle(n) if(i == n){ \ - color += CalculateParallelLight(eye, lightCollection.parallel[n], material);\ -} -#define UnfoldParallel UnfoldParallelSingle(0)\ - UnfoldParallelSingle(1)\ - UnfoldParallelSingle(2)\ - UnfoldParallelSingle(3)\ - UnfoldParallelSingle(4) -#define UnfoldPointSingle(n) if(i == n){ \ - color += CalculatePointLight(eye, lightCollection.point[n], material);\ -} -#define UnfoldPoint UnfoldPointSingle(0)\ - UnfoldPointSingle(1)\ - UnfoldPointSingle(2)\ - UnfoldPointSingle(3)\ - UnfoldPointSingle(4) -#define UnfoldSpotSingle(n) if(i == n){ \ - color += CalculateSpotLight(eye, lightCollection.spot[n], material);\ -} -#define UnfoldSpot UnfoldSpotSingle(0)\ - UnfoldSpotSingle(1)\ - UnfoldSpotSingle(2)\ - UnfoldSpotSingle(3)\ - UnfoldSpotSingle(4) - - struct Attenuation { float range; float constant; @@ -66,9 +40,9 @@ struct LightCollectionTotal { struct LightCollection { vec3 ambient; LightCollectionTotal total; - ParallelLight parallel[1]; - PointLight point[1]; - SpotLight spot[1]; + ParallelLight parallel[4]; + PointLight point[4]; + SpotLight spot[4]; }; struct PureColorMaterial { @@ -90,7 +64,7 @@ in vec3 vNormal; out vec4 fragColor; -vec3 CalculatePointlLight(Eye eye, PointLight light, PureColorMaterial material) { +vec3 CalculatePointLight(Eye eye, PointLight light, PureColorMaterial material) { vec3 lightDirection = normalize(light.position - vPosition); float diffuseFactor = max(dot(vNormal, lightDirection), 0.0) * light.intensity; @@ -146,16 +120,46 @@ vec3 CalculateSpotLight(Eye eye, SpotLight light, PureColorMaterial material) { vec3 CalculateFragmentColor(Eye eye, LightCollection lightCollection, PureColorMaterial material) { vec3 color = lightCollection.ambient; for (int i = 0; i < lightCollection.total.parallel; i++) { - // UnfoldParallel - color += CalculateParallelLight(eye, lightCollection.parallel[i], material); + if(i == 0){ + color += CalculateParallelLight(eye, lightCollection.parallel[0], material); + } + if(i == 1){ + color += CalculateParallelLight(eye, lightCollection.parallel[1], material); + } + if(i == 2){ + color += CalculateParallelLight(eye, lightCollection.parallel[2], material); + } + if(i == 3){ + color += CalculateParallelLight(eye, lightCollection.parallel[3], material); + } } for (int i = 0; i < lightCollection.total.point; i++) { - // UnfoldPoint - color += CalculatePointlLight(eye, lightCollection.point[i], material); + if(i == 0){ + color += CalculatePointLight(eye, lightCollection.point[0], material); + } + if(i == 1){ + color += CalculatePointLight(eye, lightCollection.point[1], material); + } + if(i == 2){ + color += CalculatePointLight(eye, lightCollection.point[2], material); + } + if(i == 3){ + color += CalculatePointLight(eye, lightCollection.point[3], material); + } } for (int i = 0; i < lightCollection.total.spot; i++) { - // UnfoldSpot - color += CalculateSpotLight(eye, lightCollection.spot[i], material); + if(i == 0){ + color += CalculateSpotLight(eye, lightCollection.spot[0], material); + } + if(i == 1){ + color += CalculateSpotLight(eye, lightCollection.spot[1], material); + } + if(i == 2){ + color += CalculateSpotLight(eye, lightCollection.spot[2], material); + } + if(i == 3){ + color += CalculateSpotLight(eye, lightCollection.spot[3], material); + } } return color; } diff --git a/shader/flame.frag b/shader/flame.frag new file mode 100644 index 0000000..abcabe7 --- /dev/null +++ b/shader/flame.frag @@ -0,0 +1,19 @@ +#version 330 core + +uniform vec3 uColor; + +in vec3 vColor; +out vec4 FragColor; + +void main(){ + // Halo shading // + vec2 radiant = gl_PointCoord - vec2(0.5, 0.5); + float radiusSquare = dot(radiant, radiant); + if(abs(radiant.x) < 0.2 && abs(radiant.y) < 0.2){ + FragColor = vec4(vColor, 1.0); + } + else{ + discard; + } + // FragColor = vec4(vColor, 1.0); +} \ No newline at end of file diff --git a/shader/hero.frag b/shader/hero.frag index be25f1c..43620d9 100644 --- a/shader/hero.frag +++ b/shader/hero.frag @@ -40,9 +40,9 @@ struct LightCollectionTotal { struct LightCollection { vec3 ambient; LightCollectionTotal total; - ParallelLight parallel[1]; - PointLight point[1]; - SpotLight spot[1]; + ParallelLight parallel[4]; + PointLight point[4]; + SpotLight spot[4]; }; struct TextureMaterial { @@ -65,7 +65,7 @@ in vec2 vTexCoord; out vec4 fragColor; -vec3 CalculatePointlLight(Eye eye, PointLight light, TextureMaterial material) { +vec3 CalculatePointLight(Eye eye, PointLight light, TextureMaterial material) { vec3 lightDirection = normalize(light.position - vPosition); float diffuseFactor = max(dot(vNormal, lightDirection), 0.0) * light.intensity; @@ -121,13 +121,46 @@ vec3 CalculateSpotLight(Eye eye, SpotLight light, TextureMaterial material) { vec3 CalculateFragmentColor(Eye eye, LightCollection lightCollection, TextureMaterial material) { vec3 color = lightCollection.ambient; for (int i = 0; i < lightCollection.total.parallel; i++) { - color += CalculateParallelLight(eye, lightCollection.parallel[i], material); + if(i == 0){ + color += CalculateParallelLight(eye, lightCollection.parallel[0], material); + } + if(i == 1){ + color += CalculateParallelLight(eye, lightCollection.parallel[1], material); + } + if(i == 2){ + color += CalculateParallelLight(eye, lightCollection.parallel[2], material); + } + if(i == 3){ + color += CalculateParallelLight(eye, lightCollection.parallel[3], material); + } } for (int i = 0; i < lightCollection.total.point; i++) { - color += CalculatePointlLight(eye, lightCollection.point[i], material); + if(i == 0){ + color += CalculatePointLight(eye, lightCollection.point[0], material); + } + if(i == 1){ + color += CalculatePointLight(eye, lightCollection.point[1], material); + } + if(i == 2){ + color += CalculatePointLight(eye, lightCollection.point[2], material); + } + if(i == 3){ + color += CalculatePointLight(eye, lightCollection.point[3], material); + } } for (int i = 0; i < lightCollection.total.spot; i++) { - color += CalculateSpotLight(eye, lightCollection.spot[i], material); + if(i == 0){ + color += CalculateSpotLight(eye, lightCollection.spot[0], material); + } + if(i == 1){ + color += CalculateSpotLight(eye, lightCollection.spot[1], material); + } + if(i == 2){ + color += CalculateSpotLight(eye, lightCollection.spot[2], material); + } + if(i == 3){ + color += CalculateSpotLight(eye, lightCollection.spot[3], material); + } } return color * 5; } diff --git a/shader/particle.frag b/shader/particle.frag index 50f041a..d9a17b1 100644 --- a/shader/particle.frag +++ b/shader/particle.frag @@ -1,7 +1,6 @@ #version 330 core -uniform vec3 uColor; - +in vec3 vColor; out vec4 FragColor; void main(){ @@ -9,13 +8,13 @@ void main(){ vec2 radiant = gl_PointCoord - vec2(0.5, 0.5); float radiusSquare = dot(radiant, radiant); if(abs(radiant.x) < 0.07 && abs(radiant.y) < 0.07){ - FragColor = vec4(uColor, 1.0); + FragColor = vec4(vColor, 1.0); } else if(radiusSquare < 0.25){ // from 0.0625 to 0.25 - FragColor = vec4(uColor, 0.25 - radiusSquare); + FragColor = vec4(vColor, 0.25 - radiusSquare); } else{ discard; } - // FragColor = vec4(uColor, 1.0); + // FragColor = vec4(vColor, 1.0); } \ No newline at end of file diff --git a/shader/particle.vert b/shader/particle.vert index 1018b0c..1acbfef 100644 --- a/shader/particle.vert +++ b/shader/particle.vert @@ -1,14 +1,18 @@ #version 330 core layout (location = 0) in vec3 aPoint; -layout (location = 1) in float aRadius; +layout (location = 1) in float aRadius; +layout (location = 2) in vec3 aColor; uniform mat4 uModelMatrix; uniform mat4 uViewMatrix; uniform mat4 uProjectionMatrix; +out vec3 vColor; + void main() { gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aPoint,1.0f); gl_PointSize = aRadius * 2; + vColor = aColor; } \ No newline at end of file diff --git a/src/controller_utility/character.cc b/src/controller_utility/character.cc index 46c86d1..91623de 100644 --- a/src/controller_utility/character.cc +++ b/src/controller_utility/character.cc @@ -11,7 +11,7 @@ using std::endl; float Character::static_pace_(100); -Character::Character(World* world, Object* obj, float speed):max_speed_(speed),world_(world), object_(obj){ } +Character::Character(World* world, Object* obj): world_(world), object_(obj){ } Character::~Character(){ } void Character::Bind(Object* obj){ object_ = obj; @@ -59,22 +59,28 @@ void Character::ResetRotate(void){ return ; } void Character::LaserAttack(void){ + static Timer::TimingId laser_timer = Timer::New(); + if(Timer::Query(laser_timer) < laser_attack_freq_)return; + Timer::Pin(laser_timer); world_->temp_.PushBack( new Particle( world_, nullptr, - new PureColorMaterial(color::Red(), color::Red(), 40), + new PureColorMaterial(laser_attack_color_, laser_attack_color_, 40), object_->GetOrigin(), - glm::vec3(0.1, 0, 0), + glm::vec3(0.25, 0, 0), kSmallParticle | kFloatParticle | kLaserParticle, 10, - 0.02, + 0.05, 1 ), 2 ); } void Character::BoxAttack(void){ + static Timer::TimingId box_timer = Timer::New(); + if(Timer::Query(box_timer) < box_attack_freq_)return; + Timer::Pin(box_timer); btVector3 origin = object_->GetOrigin(); btTransform transform; for(int i = 0; i < 10; i++){ @@ -83,19 +89,49 @@ void Character::BoxAttack(void){ Object* temp = new PlainBox( world_, nullptr, - new PureColorMaterial(color::Red(), color::Red(), 40), + new PureColorMaterial(box_attack_color_, box_attack_color_, 40), transform, glm::vec3(0.4, 0.4, 0.4), 5 ); temp->ActivateControl(); float a = Random::QueryFloatRandom(0, 20),b = Random::QueryFloatRandom(- 30, 30); - cout << "New bullet: " << a << ", " << b << endl; temp->SetVelocity(btVector3(60, a, b)); // temp->SetVelocity(btVector3(8, Random::QueryFloatRandom(-2,5), Random::QueryFloatRandom(-5, 5))); world_->temp_.PushBack( temp, 10 ); } - +} +void Character::Lose(float amount){ + auto particle = std::make_shared( + world_, + new Shader("shader/particle.vert", "shader/blood_decr.frag"), + new PureColorMaterial(color::Red(), color::Red(), 40), + btVector3(0, 0, 0), // position + glm::vec3(0, 0.005, 0), + kMediumParticle | kFloatParticle | kAmbientParticle | kJitterParticle, + (int)(amount / 2.0), + 1.0f + ); + particle->Attach(object_, btVector3(0,3,0)); + world_->temp_.PushBack( + particle, 7 + ); +} +void Character::Gain(float amount){ + auto particle = std::make_shared( + world_, + new Shader("shader/particle.vert", "shader/blood_incr.frag"), + new PureColorMaterial(color::Green(), color::Green(), 40), + btVector3(0, 0, 0), // position + glm::vec3(0, 0.005, 0), + kMediumParticle | kFloatParticle | kAmbientParticle | kJitterParticle, + (int)(amount / 2.0), + 2.0f + ); + particle->Attach(object_, btVector3(0,3,0)); + world_->temp_.PushBack( + particle, 7 + ); } \ No newline at end of file diff --git a/src/debug_utility/cg_exception.cc b/src/debug_utility/cg_exception.cc index ddb3fc0..2491ed9 100644 --- a/src/debug_utility/cg_exception.cc +++ b/src/debug_utility/cg_exception.cc @@ -1,7 +1,10 @@ +#include + #include "debug_utility/cg_exception.h" FileNotExistsError::FileNotExistsError(const std::string &path) { error_message = "[file error] File not exists at " + path; + std::cout << error_message << std::endl; } const char *FileNotExistsError::what() const noexcept { @@ -10,6 +13,7 @@ const char *FileNotExistsError::what() const noexcept { ShaderCompileError::ShaderCompileError(const std::string &title, const std::string &log) { error_message = "[shader compile error on " + title + "] " + log; + std::cout << error_message << std::endl; } const char *ShaderCompileError::what() const noexcept { @@ -18,6 +22,7 @@ const char *ShaderCompileError::what() const noexcept { ShaderLinkError::ShaderLinkError(const std::string &log) { error_message = "[shader link error] " + log; + std::cout << error_message << std::endl; } const char *ShaderLinkError::what() const noexcept { @@ -26,6 +31,7 @@ const char *ShaderLinkError::what() const noexcept { LoadPictureError::LoadPictureError(const std::string &path) { error_message = "[picture format error] Fail to load picture at " + path; + std::cout << error_message << std::endl; } const char *LoadPictureError::what() const noexcept { @@ -34,6 +40,7 @@ const char *LoadPictureError::what() const noexcept { AssimpError::AssimpError(const std::string &error_string) { error_message = "[assimp error] " + error_string; + std::cout << error_message << std::endl; } const char *AssimpError::what() const noexcept { @@ -42,6 +49,7 @@ const char *AssimpError::what() const noexcept { ShaderSettingError::ShaderSettingError(const std::string &name) { error_message = "[shader setting error] Fail to set uniform variable " + name; + std::cout << error_message << std::endl; } const char *ShaderSettingError::what() const noexcept { diff --git a/src/object.cc b/src/object.cc index 019cfaf..d2fc7e5 100644 --- a/src/object.cc +++ b/src/object.cc @@ -26,12 +26,13 @@ Object::Object(World* w, Shader* shader, Material* material, uint32_t stride, bo } Object::~Object(){ + // cout << __func__ << endl; // delete from Graphics glDeleteVertexArrays(1, &vao_); glDeleteBuffers(1, &vbo_); glDeleteBuffers(1, &ebo_); // delete from bullet - if(bt_object_)world_->bt_world_->removeCollisionObject(bt_object_); + if(bt_object_ && world_ && world_->bt_world_ && !World::exit)world_->bt_world_->removeCollisionObject(bt_object_); // DeleteFromPhysics(); delete shader_; delete bt_object_; diff --git a/src/particle.cc b/src/particle.cc index e0649a7..8fb13f5 100644 --- a/src/particle.cc +++ b/src/particle.cc @@ -24,15 +24,15 @@ ParticleConfig::ParticleConfig(glm::vec3 v, Color color, int intFlag): } switch(flags & 0x0c){ case (kLargeParticle): - major_radius = 8; - variance_radius = 4; + major_radius = 12; + variance_radius = 6; break; case (kMediumParticle): major_radius = 5; variance_radius = 3; break; default: - major_radius = 2; + major_radius = 3.5; variance_radius = 1; } switch(flags & 0x10){ @@ -61,11 +61,11 @@ ParticleConfig::ParticleConfig(glm::vec3 v, Color color, int intFlag): else{ jitter = false; } - if(flags & kInnerParticle){ - inner_force = true; + if(flags & kMockFlame){ + mock_flame = true; } else{ - inner_force = false; + mock_flame = false; } } @@ -83,6 +83,24 @@ ParticleConfig::ParticleConfig(glm::vec3 v, Color color, int intFlag): // } ParticleEmitter::ParticleEmitter(ParticleConfig config):config_(config){ } void ParticleEmitter::Emit(std::vector::iterator curslot, glm::vec3 p){ + if(config_.mock_flame){ + glm::vec3 offset(Random::QueryFloatRandom(0,1) * Random::QueryFloatRandom(0,1) * 7, 0, Random::QueryFloatRandom(0,1) * Random::QueryFloatRandom(0,1) * 7 ); + float seed = sqrt(offset[0] / 7 + offset[1] / 7); + if((int)(seed * 7) % 2 == 0)offset[0] *= -1; + if((int)(seed * 13) % 2 == 1)offset[2] *= -1; + glm::vec3 position = p + offset; // near center + glm::vec3 v = config_.major_velocity * (1 - seed); + Color color = config_.major_color * ((2 - seed) * 3.0f); + float radius = config_.major_radius * ( 2 - seed); + *curslot = ParticleInfo( + position, + v, + config_.acceleration, + radius, + color + ); + return ; + } // system("pause"); glm::vec3 v = config_.major_velocity; float min_component = 0.5 + std::min(std::min(fabs(v[0]),fabs(v[1])),fabs(v[2])); // min has largest var, others small var @@ -100,7 +118,7 @@ void ParticleEmitter::Emit(std::vector::iterator curslot, glm::vec if(!config_.gradual)factor = Random::QueryFloatRandom(0, 1); color[2] += config_.delta_color[2] * factor; if(config_.jitter){ - p += glm::vec3(Random::QueryFloatRandom(-1,1), 0, Random::QueryFloatRandom(-1,1)); + p += glm::vec3(Random::QueryFloatRandom(-3,3), 0, Random::QueryFloatRandom(-3,3)); } *curslot = ParticleInfo( p, @@ -122,7 +140,7 @@ Particle::Particle( float interval, float duration ): - Object(world, shader, material, 4, false), + Object(world, shader, material, 7, false), position_(position), amount_(amount), particles_(amount), @@ -133,7 +151,7 @@ Particle::Particle( LOG(); interval_timer_ = Timer::New(); duration_timer_ = Timer::New(); - data_.resize(amount_ * 4); + data_.resize(amount_ * 7); if(!shader_)shader_ = new Shader("shader/particle.vert", "shader/particle.frag"); InitMesh(); @@ -156,10 +174,12 @@ void Particle::ImportToGraphics(){ // No bind ebo glBindBuffer(GL_ARRAY_BUFFER, vbo_); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * data_.size(), data_.data(), GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*) 0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*) 0); glEnableVertexAttribArray(0); - glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*) (3 * sizeof(float))); + glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*) (3 * sizeof(float))); glEnableVertexAttribArray(1); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*) (4 * sizeof(float))); + glEnableVertexAttribArray(2); glBindVertexArray(0); } @@ -173,14 +193,17 @@ void Particle::Draw(Camera* camera, const LightCollection* lights) { // last_time = current_time; for(int i = 0; i < amount_; i++){ particles_[i].Update(delta_time); - data_[4*i + 0] = particles_[i].position[0]; - data_[4*i + 1] = particles_[i].position[1]; - data_[4*i + 2] = particles_[i].position[2]; - data_[4*i + 3] = particles_[i].radius; + data_[7*i + 0] = particles_[i].position[0]; + data_[7*i + 1] = particles_[i].position[1]; + data_[7*i + 2] = particles_[i].position[2]; + data_[7*i + 3] = particles_[i].radius; + data_[7*i + 4] = particles_[i].color[0]; + data_[7*i + 5] = particles_[i].color[1]; + data_[7*i + 6] = particles_[i].color[2]; } ImportToGraphics(); shader_->Use(); - shader_->SetUniform("uColor", dynamic_cast(material_)->diffuse()); + // shader_->SetUniform("uColor", dynamic_cast(material_)->diffuse()); btTransform transform; transform.setIdentity(); diff --git a/src/player_utility/player_collection.cc b/src/player_utility/player_collection.cc index 9d61ca8..af38281 100644 --- a/src/player_utility/player_collection.cc +++ b/src/player_utility/player_collection.cc @@ -45,7 +45,7 @@ void PlayerCollection::Traverse(std::function)> yield void PlayerCollection::InitPlayerCollection(World *world_ptr, std::vector& objects) { btTransform transform; transform.setIdentity(); - transform.setOrigin(World::origin + btVector3(0, World::character_height, -World::character_height)); + transform.setOrigin(World::origin + btVector3(45, 40, 30)); Object *object_ptr = new Hero( world_ptr, diff --git a/src/stage.cc b/src/stage.cc index 0e54855..de8f2f0 100644 --- a/src/stage.cc +++ b/src/stage.cc @@ -21,6 +21,148 @@ void Stage::InitStage(StageFlag flag){ } } void Stage::InitDungeonStage(void){ + // Safe bound + btTransform bounding; + bounding.setIdentity(); + bounding.setOrigin(btVector3(0, 0, -10)); + world_->CreateRigidBody( + 0, + bounding, + new btBoxShape(btVector3(500, 500, 1)) + ); + // Ground aka Wall // + btScalar thickness = 5; + btScalar depth = 40; + btScalar width = 270; + btTransform transGround; + transGround.setIdentity(); + transGround.setOrigin(btVector3( width / 2.0, -thickness / 2.0, depth / 2.0)); // place in positive quadrant + // transGround.setOrigin(btVector3(0, -thickness / 2.0 , 0)); + btMatrix3x3 orn = transGround.getBasis(); + orn *= btMatrix3x3(btQuaternion(btVector3(1, 0, 0), glm::pi() / 2.0) ); + transGround.setBasis(orn); + objects_.push_back( + StageWrapper(std::make_shared( + world_, + nullptr, + new PureColorMaterial(color::White(), color::White(), 3), + transGround, + thickness, + glm::vec3(width / 2, depth / 2.0, 0) + )) + ); + // Main Wall // + btScalar height = 45; + btTransform transWall; + transWall.setIdentity(); + transWall.setOrigin(btVector3(width / 2.0, height / 2.0, depth - thickness / 2.0)); + objects_.push_back( + StageWrapper(std::make_shared( + world_, + nullptr, + new PureColorMaterial(color::White(), color::White(), 2), + transWall, + thickness, + glm::vec3(width / 2.0, height / 2.0, 0) + )) + ); + // Platform // + btScalar platformHeight = 35; + btScalar platformWidth = 40; + btScalar platformOffset = 40; + btScalar platformProtrude = 12; + btTransform transPlatform; + transPlatform.setIdentity(); + transPlatform.setOrigin(btVector3(platformOffset + platformWidth / 2.0, platformHeight, depth - platformProtrude / 2.0 - thickness / 2.0)); + orn = transPlatform.getBasis() * btMatrix3x3(btQuaternion(btVector3(1,0,0), glm::pi() / 2.0)); + transPlatform.setBasis(orn); + objects_.push_back( + StageWrapper(std::make_shared( + world_, + nullptr, + new PureColorMaterial(color::White(), color::White(), 2), + transPlatform, + thickness, + glm::vec3(platformWidth / 2.0, platformProtrude / 2.0, 0) + )) + ); + // Stair + int firstLevelStair = 3; + btScalar stairWidth = platformOffset / (firstLevelStair + 1); + btScalar stairDeltaHeight = platformHeight / 2.0 / (firstLevelStair + 1); + btTransform transStair; + transStair = transPlatform; + for(int i = 0; i < firstLevelStair; i++){ + transStair.setOrigin(btVector3(platformOffset - stairWidth * i - stairWidth / 2.0, platformHeight - stairDeltaHeight * (i+1), depth - platformProtrude / 2.0 - thickness / 2.0 )); + objects_.push_back( + StageWrapper(std::make_shared( + world_, + nullptr, + new PureColorMaterial(color::White(), color::White(), 2), + transStair, + thickness, + glm::vec3(stairWidth / 2.0, platformProtrude / 2.0, 0) + )) + ); + } + btScalar stairProtrude = 1.8 * platformProtrude; + transStair.setOrigin(btVector3(stairWidth / 2.0, platformHeight / 2.0, depth - stairProtrude / 2.0 - thickness / 2.0 )); + objects_.push_back( + StageWrapper(std::make_shared( + world_, + nullptr, + new PureColorMaterial(color::White(), color::White(), 2), + transStair, + thickness, + glm::vec3(stairWidth / 2.0, stairProtrude / 2.0, 0) + )) + ); + int secondLevelStair = 2; + stairDeltaHeight = platformHeight / 2.0 / (secondLevelStair + 1); + for(int i = 1; i <= secondLevelStair; i++){ + transStair.setOrigin(btVector3(stairWidth / 2.0 + i * stairWidth, platformHeight / 2.0 - stairDeltaHeight * i, depth - stairProtrude / 2.0 - thickness / 2.0)); + objects_.push_back( + StageWrapper(std::make_shared( + world_, + nullptr, + new PureColorMaterial(color::White(), color::White(), 2), + transStair, + thickness, + glm::vec3(stairWidth / 2.0, stairProtrude / 2.0, 0) + )) + ); + } + + // Flame Pillar // + btScalar pillarHeight = height - 10; + btScalar pillarWidth = 15; + btTransform transPillar; + transPillar.setIdentity(); + transPillar.setOrigin(btVector3(-pillarWidth / 2.0, pillarHeight / 2.0, depth - stairProtrude / 2.0 - pillarWidth / 2.0)); + objects_.push_back( + StageWrapper(std::make_shared( + world_, + nullptr, + new PureColorMaterial(color::White(), color::White(), 2), + transPillar, + pillarWidth, + glm::vec3(pillarWidth / 2.0 + 1, pillarHeight / 2.0 + 1, 0) + )) + ); + // Flame // + btVector3 posFlame(-pillarWidth / 2.0, pillarHeight, depth - stairProtrude / 2.0 - pillarWidth / 2.0); + objects_.push_back( + StageWrapper(std::make_shared( + world_, + new Shader("shader/particle.vert", "shader/flame.frag"), + new PureColorMaterial(color::Red(), color::Red(), 2), + posFlame, + glm::vec3(0, 0.007, 0), + kLargeParticle | kFlameParticle | kAmbientParticle | kJitterParticle | kMockFlame, + 20, + 0.08f + )) + ); return ; } void Stage::InitDefaultStage(void){ @@ -37,14 +179,14 @@ void Stage::InitDefaultStage(void){ orn *= btMatrix3x3(btQuaternion(btVector3(1, 0, 0), glm::pi() / 2.0)); ground_transform.setBasis(orn); objects_.push_back( - new Wall( + StageWrapper(std::make_shared( world_, nullptr, new PureColorMaterial(color::White(), color::White(), 3), ground_transform, thickness, glm::vec3(half_bound, half_bound, 0) - ) + )) ); // Wall aka Wall // // Wall Size @@ -56,17 +198,17 @@ void Stage::InitDefaultStage(void){ wall_transform.setIdentity(); wall_transform.setOrigin(btVector3(box_half * 2, wallHeight / 2 , box_half)); objects_.push_back( - new Wall( + StageWrapper(std::make_shared( world_, nullptr, new PureColorMaterial(color::White(), color::White(), 2), wall_transform, thickness, glm::vec3(wallWidth / 2, wallHeight / 2, 0) - ) + )) ); - // Item aka Wall // + // Item aka Box // btTransform box_transform; box_transform.setIdentity(); box_transform.setOrigin(World::origin + btVector3(box_half * 2, box_half, 0)); diff --git a/src/temp_collection.cc b/src/temp_collection.cc index dcb8033..f1f18cb 100644 --- a/src/temp_collection.cc +++ b/src/temp_collection.cc @@ -13,4 +13,7 @@ void TempCollection::Update(void){ } void TempCollection::PushBack(Object* object, float duration){ objects_.push_back(TempWrapper(object, duration)); +} +void TempCollection::PushBack(std::shared_ptr object, float duration){ + objects_.push_back(TempWrapper(object, duration)); } \ No newline at end of file diff --git a/src/world.cc b/src/world.cc index e29744f..cff4833 100644 --- a/src/world.cc +++ b/src/world.cc @@ -13,6 +13,7 @@ using std::shared_ptr; int World::height = 600; int World::width = 800; +bool World::exit = false; Camera* World::camera = new Camera(glm::vec3(25, 51, 25), (double) World::width / (double) World::height); LightCollection* World::light_collection = new LightCollection(glm::vec3(0, 0, 0)); @@ -111,7 +112,7 @@ void World::InitPhysics(void) { } void World::InitScene(void) { - stage_.InitStage(kDefaultStage); + stage_.InitStage(kDungeonStage); player_collection_ptr_ = new PlayerCollection(); player_collection_ptr_->InitPlayerCollection(this, objects_); @@ -130,8 +131,8 @@ void World::InitScene(void) { ); light_collection->PushBack( new SpotLight( - glm::vec3(-25, 25, -25), - glm::vec3(10, 0, 0), + glm::vec3(0, 0, 0), + glm::vec3(10, 5, 5), color::White(), 10, Attenuation(1800), @@ -201,6 +202,7 @@ void World::CursorPosCallback(GLFWwindow *window, double x, double y) { void World::KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mode) { Keyboard::shared.Trigger(key, action); if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + World::exit = true; glfwSetWindowShouldClose(window, GL_TRUE); } } \ No newline at end of file