summaryrefslogtreecommitdiffstats
path: root/src/graphics
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-08-09 22:49:13 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-08-09 22:49:13 +0200
commitacff306cc132c4f8cc71f44f85ffd7bdd18a114e (patch)
tree582ebb36e143c09761bca262fdbb1a27ec7a5b8f /src/graphics
parentc1936514c054d6d7c85843bf2c3e0b97653ef651 (diff)
downloadcolobot-acff306cc132c4f8cc71f44f85ffd7bdd18a114e.tar.gz
colobot-acff306cc132c4f8cc71f44f85ffd7bdd18a114e.tar.bz2
colobot-acff306cc132c4f8cc71f44f85ffd7bdd18a114e.zip
CPlanet implementation
Added rewritten CPlanet implementation
Diffstat (limited to 'src/graphics')
-rw-r--r--src/graphics/engine/planet.cpp164
-rw-r--r--src/graphics/engine/planet.h72
2 files changed, 209 insertions, 27 deletions
diff --git a/src/graphics/engine/planet.cpp b/src/graphics/engine/planet.cpp
index 4f1f614..022de66 100644
--- a/src/graphics/engine/planet.cpp
+++ b/src/graphics/engine/planet.cpp
@@ -19,5 +19,167 @@
#include "graphics/engine/planet.h"
+#include "common/iman.h"
+#include "graphics/core/device.h"
+#include "graphics/engine/engine.h"
-// TODO implementation
+
+const int PLANET_PREALLOCATE_COUNT = 10;
+
+
+Gfx::CPlanet::CPlanet(CInstanceManager* iMan, Gfx::CEngine* engine)
+{
+ m_iMan = iMan;
+ m_iMan->AddInstance(CLASS_PLANET, this);
+
+ m_planet[0].reserve(PLANET_PREALLOCATE_COUNT);
+ m_planet[1].reserve(PLANET_PREALLOCATE_COUNT);
+
+ m_engine = engine;
+ Flush();
+
+}
+
+Gfx::CPlanet::~CPlanet()
+{
+ m_iMan = nullptr;
+}
+
+void Gfx::CPlanet::Flush()
+{
+ for (int j = 0; j < 2; j++)
+ m_planet[j].clear();
+
+ m_planetExist = false;
+ m_mode = 0;
+ m_time = 0.0f;
+}
+
+bool Gfx::CPlanet::EventProcess(const Event &event)
+{
+ if (event.type == EVENT_FRAME)
+ return EventFrame(event);
+
+ return true;
+}
+
+bool Gfx::CPlanet::EventFrame(const Event &event)
+{
+ if (m_engine->GetPause()) return true;
+
+ m_time += event.rTime;
+
+ for (int i = 0; i < static_cast<int>( m_planet[m_mode].size() ); i++)
+ {
+ float a = m_time*m_planet[m_mode][i].speed;
+ if (a < 0.0f)
+ a += Math::PI*1000.0f;
+
+ m_planet[m_mode][i].angle.x = a+m_planet[m_mode][i].start.x;
+ m_planet[m_mode][i].angle.y = sinf(a)*sinf(m_planet[m_mode][i].dir)+m_planet[m_mode][i].start.y;
+ }
+
+ return true;
+}
+
+void Gfx::CPlanet::LoadTexture()
+{
+ for (int j = 0; j < 2; j++)
+ {
+ for (int i = 0; i < static_cast<int>( m_planet[j].size() ); i++)
+ {
+ m_engine->LoadTexture(m_planet[j][i].name);
+ }
+ }
+}
+
+void Gfx::CPlanet::Draw()
+{
+ Gfx::CDevice* device = m_engine->GetDevice();
+ float eyeDirH = m_engine->GetEyeDirH();
+ float eyeDirV = m_engine->GetEyeDirV();
+
+ Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal
+ float dp = 0.5f/256.0f;
+
+ for (int i = 0; i < static_cast<int>( m_planet[m_mode].size() ); i++)
+ {
+ m_engine->SetTexture(m_planet[m_mode][i].name);
+
+ if (m_planet[m_mode][i].transparent)
+ m_engine->SetState(Gfx::ENG_RSTATE_WRAP | Gfx::ENG_RSTATE_ALPHA);
+ else
+ m_engine->SetState(Gfx::ENG_RSTATE_WRAP | Gfx::ENG_RSTATE_TTEXTURE_BLACK);
+
+ Math::Point p1, p2;
+
+ float a = eyeDirH + m_planet[m_mode][i].angle.x;
+ p1.x = Math::Mod(a, Math::PI*2.0f)-0.5f;
+
+ a = eyeDirV + m_planet[m_mode][i].angle.y;
+ p1.y = 0.4f+(Math::Mod(a+Math::PI, Math::PI*2.0f)-Math::PI)*(2.0f/Math::PI);
+
+ p1.x -= m_planet[m_mode][i].dim/2.0f*0.75f;
+ p1.y -= m_planet[m_mode][i].dim/2.0f;
+ p2.x = p1.x+m_planet[m_mode][i].dim*0.75f;
+ p2.y = p1.y+m_planet[m_mode][i].dim;
+
+ float u1 = m_planet[m_mode][i].uv1.x + dp;
+ float v1 = m_planet[m_mode][i].uv1.y + dp;
+ float u2 = m_planet[m_mode][i].uv2.x - dp;
+ float v2 = m_planet[m_mode][i].uv2.y - dp;
+
+ Gfx::Vertex quad[4] =
+ {
+ Gfx::Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(u1, v2)),
+ Gfx::Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(u1, v1)),
+ Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(u2, v2)),
+ Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(u2, v1))
+ };
+
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);
+ m_engine->AddStatisticTriangle(2);
+ }
+}
+
+void Gfx::CPlanet::Create(int mode, Math::Point start, float dim, float speed,
+ float dir, const std::string& name, Math::Point uv1, Math::Point uv2)
+{
+ if (mode < 0) mode = 0;
+ if (mode > 1) mode = 1;
+
+ Gfx::Planet planet;
+
+ planet.start = start;
+ planet.angle = start;
+ planet.dim = dim;
+ planet.speed = speed;
+ planet.dir = dir;
+
+ planet.name = name;
+ planet.uv1 = uv1;
+ planet.uv2 = uv2;
+
+ planet.transparent = planet.name.find("planet") != std::string::npos;
+
+ m_planet[mode].push_back(planet);
+
+ m_planetExist = true;
+}
+
+bool Gfx::CPlanet::PlanetExist()
+{
+ return m_planetExist;
+}
+
+void Gfx::CPlanet::SetMode(int mode)
+{
+ if (mode < 0) mode = 0;
+ if (mode > 1) mode = 1;
+ m_mode = mode;
+}
+
+int Gfx::CPlanet::GetMode()
+{
+ return m_mode;
+}
diff --git a/src/graphics/engine/planet.h b/src/graphics/engine/planet.h
index 264d05c..5ba318b 100644
--- a/src/graphics/engine/planet.h
+++ b/src/graphics/engine/planet.h
@@ -22,6 +22,8 @@
#include "common/event.h"
#include "math/point.h"
+#include <vector>
+
class CInstanceManager;
@@ -30,51 +32,69 @@ namespace Gfx {
class CEngine;
-
-const short MAXPLANET = 10;
-
struct Planet
{
- char bUsed; // TRUE -> planet exists
- Math::Point start; // initial position in degrees
- Math::Point angle; // current position in degrees
- float dim; // dimensions (0..1)
- float speed; // speed
- float dir; // direction in the sky
- char name[20]; // name of the texture
- Math::Point uv1, uv2; // texture mapping
- char bTGA; // texture .TGA
+ //! Initial position in degrees
+ Math::Point start;
+ //! Current position in degrees
+ Math::Point angle;
+ //! Dimensions (0..1)
+ float dim;
+ //! Speed
+ float speed;
+ //! Direction in the sky
+ float dir;
+ //! Name of the texture
+ std::string name;
+ //! Texture mapping
+ Math::Point uv1, uv2;
+ //! Transparent texture
+ bool transparent;
+
+ Planet()
+ {
+ dim = speed = dir = 0.0f;
+ transparent = false;
+ }
};
-
-
-
-class CPlanet {
+class CPlanet
+{
public:
- CPlanet(CInstanceManager* iMan, CEngine* engine);
+ CPlanet(CInstanceManager* iMan, Gfx::CEngine* engine);
~CPlanet();
+ //! Removes all the planets
void Flush();
+ //! Management of an event
bool EventProcess(const Event &event);
- bool Create(int mode, Math::Point start, float dim, float speed, float dir, char *name, Math::Point uv1, Math::Point uv2);
+ //! Creates a new planet
+ void Create(int mode, Math::Point start, float dim, float speed, float dir,
+ const std::string& name, Math::Point uv1, Math::Point uv2);
+ //! Indicates if there is at least one planet
bool PlanetExist();
+ //! Load all the textures for the planets
void LoadTexture();
+ //! Draws all the planets
void Draw();
+ //@{
+ //! Choice of mode
void SetMode(int mode);
- int RetMode();
+ int GetMode();
+ //@}
protected:
+ //! Makes the planets evolve
bool EventFrame(const Event &event);
protected:
- CInstanceManager* m_iMan;
- CEngine* m_engine;
+ CInstanceManager* m_iMan;
+ Gfx::CEngine* m_engine;
- float m_time;
- int m_mode;
- Planet m_planet[2][MAXPLANET];
- bool m_bPlanetExist;
+ float m_time;
+ int m_mode;
+ std::vector<Gfx::Planet> m_planet[2];
+ bool m_planetExist;
};
-
}; // namespace Gfx