summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-07-22 22:05:12 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-07-22 22:05:12 +0200
commit8797569d33c4917eb8f8a1dc2341aac7b5815315 (patch)
tree839aca030b0d3ed36cef15b051fbfd4bf8ecb754 /src
parent86ea086790a677d6de6a836e7562814d3ba30bd1 (diff)
downloadcolobot-8797569d33c4917eb8f8a1dc2341aac7b5815315.tar.gz
colobot-8797569d33c4917eb8f8a1dc2341aac7b5815315.tar.bz2
colobot-8797569d33c4917eb8f8a1dc2341aac7b5815315.zip
Texture & mouse functions; refactoring & fixes
- cleaned up and added documentation to engine.h - refactored CEngine interface and associated structs - added mouse handling functions in CApplication & CEngine - fixed bugs in projection matrix setting - changed texture loading & handling - added const-values in CDevice & CGLDevice - changed event management in CApplication - other minor changes & bugfixes
Diffstat (limited to 'src')
-rw-r--r--src/app/app.cpp208
-rw-r--r--src/app/app.h67
-rw-r--r--src/app/main.cpp4
-rw-r--r--src/common/event.h7
-rw-r--r--src/common/key.h4
-rw-r--r--src/common/singleton.h10
-rw-r--r--src/graphics/common/camera.h2
-rw-r--r--src/graphics/common/color.h16
-rw-r--r--src/graphics/common/device.h23
-rw-r--r--src/graphics/common/engine.cpp646
-rw-r--r--src/graphics/common/engine.h726
-rw-r--r--src/graphics/common/light.h4
-rw-r--r--src/graphics/common/particle.h4
-rw-r--r--src/graphics/common/texture.h41
-rw-r--r--src/graphics/opengl/gldevice.cpp156
-rw-r--r--src/graphics/opengl/gldevice.h31
-rw-r--r--src/graphics/opengl/glengine.cpp21
-rw-r--r--src/graphics/opengl/glengine.h32
-rw-r--r--src/graphics/opengl/test/model_test.cpp16
-rw-r--r--src/graphics/opengl/test/texture_test.cpp12
-rw-r--r--src/graphics/opengl/test/transform_test.cpp6
-rw-r--r--src/math/geometry.h20
22 files changed, 1488 insertions, 568 deletions
diff --git a/src/app/app.cpp b/src/app/app.cpp
index 6a71f64..4812102 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -22,6 +22,7 @@
#include "app/system.h"
#include "common/logger.h"
#include "common/iman.h"
+#include "common/image.h"
#include "graphics/opengl/gldevice.h"
@@ -31,6 +32,9 @@
#include <stdio.h>
+template<> CApplication* CSingleton<CApplication>::mInstance = NULL;
+
+
//! Interval of timer called to update joystick state
const int JOYSTICK_TIMER_INTERVAL = 1000/30;
@@ -70,14 +74,9 @@ struct ApplicationPrivate
};
-CApplication* CApplication::m_appInstance = NULL;
-
CApplication::CApplication()
{
- assert(m_appInstance == NULL);
- m_appInstance = this;
-
m_private = new ApplicationPrivate();
m_exitCode = 0;
@@ -107,6 +106,8 @@ CApplication::CApplication()
m_debugMode = false;
m_setupMode = true;
+ m_dataPath = "./data";
+
ResetKey();
}
@@ -120,29 +121,49 @@ CApplication::~CApplication()
delete m_iMan;
m_iMan = NULL;
-
- m_appInstance = NULL;
}
-Error CApplication::ParseArguments(int argc, char *argv[])
+bool CApplication::ParseArguments(int argc, char *argv[])
{
+ bool waitDataDir = false;
+
for (int i = 1; i < argc; ++i)
{
std::string arg = argv[i];
+ if (waitDataDir)
+ {
+ waitDataDir = false;
+ m_dataPath = arg;
+ }
+
if (arg == "-debug")
{
m_showStats = true;
SetDebugMode(true);
}
- // TODO else {} report invalid argument
+ else if (arg == "-datadir")
+ {
+ waitDataDir = true;
+ }
+ else
+ {
+ m_exitCode = 1;
+ return false;
+ }
}
- return ERR_OK;
+ // Data dir not given?
+ if (waitDataDir)
+ return false;
+
+ return true;
}
bool CApplication::Create()
{
+ // TODO: verify that data directory exists
+
// Temporarily -- only in windowed mode
m_private->deviceConfig.fullScreen = false;
@@ -365,7 +386,7 @@ void CApplication::CloseJoystick()
Uint32 JoystickTimerCallback(Uint32 interval, void *)
{
- CApplication *app = CApplication::GetInstance();
+ CApplication *app = CApplication::GetInstancePointer();
if ((app == NULL) || (! app->GetJoystickEnabled()))
return 0; // don't run the timer again
@@ -434,43 +455,82 @@ int CApplication::Run()
{
m_active = true;
- while (m_private->currentEvent.type != SDL_QUIT)
+ while (true)
{
// Use SDL_PeepEvents() if the app is active, so we can use idle time to
// render the scene. Else, use SDL_PollEvent() to avoid eating CPU time.
int count = 0;
- if (m_active)
- {
- SDL_PumpEvents();
- count = SDL_PeepEvents(&m_private->currentEvent, 1, SDL_GETEVENT, SDL_ALLEVENTS);
- }
- else
- {
- SDL_PollEvent(&m_private->currentEvent);
- }
- // If received an event
- if ((m_active && count > 0) || (!m_active))
+ // To be sure no old event remains
+ m_private->currentEvent.type = SDL_NOEVENT;
+
+ bool haveEvent = true;
+ while (haveEvent)
{
- ParseEvent();
+ haveEvent = false;
+
+ if (m_active)
+ {
+ SDL_PumpEvents();
+ count = SDL_PeepEvents(&m_private->currentEvent, 1, SDL_GETEVENT, SDL_ALLEVENTS);
+ }
+ else
+ {
+ count = SDL_PollEvent(&m_private->currentEvent);
+ }
+
+ // If received an event
+ if (count > 0)
+ {
+ haveEvent = true;
+
+ Event event = ParseEvent();
+
+ if (event.type == EVENT_QUIT)
+ goto end; // exit the loop
+
+ if (event.type != EVENT_NULL)
+ {
+ bool passOn = ProcessEvent(event);
+
+ if (m_engine != NULL && passOn)
+ passOn = m_engine->ProcessEvent(event);
+
+ if (passOn)
+ m_eventQueue->AddEvent(event);
+ }
+ }
}
- // Render a frame during idle time (no messages are waiting)
+ // Enter game update & frame rendering only if active
if (m_active && m_ready)
{
Event event;
while (m_eventQueue->GetEvent(event))
{
if (event.type == EVENT_QUIT)
- {
goto end; // exit both loops
+
+ bool passOn = true;
+
+ // Skip system events (they have been processed earlier)
+ if (! event.systemEvent)
+ {
+ passOn = ProcessEvent(event);
+
+ if (passOn && m_engine != NULL)
+ passOn = m_engine->ProcessEvent(event);
}
- //m_robotMain->EventProcess(event);
+ /*if (passOn && m_robotMain != NULL)
+ m_robotMain->ProcessEvent(event); */
}
+ // Update game and render a frame during idle time (no messages are waiting)
+ bool ok = Render();
+
// If an error occurs, push quit event to the queue
- if (! Render())
+ if (! ok)
{
SDL_Event quitEvent;
memset(&quitEvent, 0, sizeof(SDL_Event));
@@ -481,7 +541,6 @@ int CApplication::Run()
}
end:
- //m_sound->StopMusic();
Destroy();
return m_exitCode;
@@ -501,23 +560,34 @@ PressState TranslatePressState(unsigned char state)
return STATE_RELEASED;
}
-/** Conversion of the position of the mouse to the following coordinates:
-
-x: 0=left, 1=right
+/** Conversion of the position of the mouse from window coords to interface coords:
+ - x: 0=left, 1=right
+ - y: 0=down, 1=up */
+Math::Point CApplication::WindowToInterfaceCoords(Math::IntPoint pos)
+{
+ return Math::Point( (float)pos.x / (float)m_private->deviceConfig.width,
+ 1.0f - (float)pos.y / (float)m_private->deviceConfig.height);
+}
-y: 0=down, 1=up
-*/
-Math::Point CApplication::WindowToInterfaceCoords(int x, int y)
+Math::IntPoint CApplication::InterfaceToWindowCoords(Math::Point pos)
{
- return Math::Point((float)x / (float)m_private->deviceConfig.width,
- 1.0f - (float)y / (float)m_private->deviceConfig.height);
+ return Math::IntPoint((int)(pos.x * m_private->deviceConfig.width),
+ (int)((1.0f - pos.y) * m_private->deviceConfig.height));
}
-void CApplication::ParseEvent()
+/** The SDL event parsed is stored internally.
+ If event is not available or is not understood, returned event is of type EVENT_NULL. */
+Event CApplication::ParseEvent()
{
Event event;
- if ( (m_private->currentEvent.type == SDL_KEYDOWN) ||
+ event.systemEvent = true;
+
+ if (m_private->currentEvent.type == SDL_QUIT)
+ {
+ event.type = EVENT_QUIT;
+ }
+ else if ( (m_private->currentEvent.type == SDL_KEYDOWN) ||
(m_private->currentEvent.type == SDL_KEYUP) )
{
if (m_private->currentEvent.type == SDL_KEYDOWN)
@@ -540,16 +610,15 @@ void CApplication::ParseEvent()
event.mouseButton.button = m_private->currentEvent.button.button;
event.mouseButton.state = TranslatePressState(m_private->currentEvent.button.state);
- event.mouseButton.pos = WindowToInterfaceCoords(m_private->currentEvent.button.x, m_private->currentEvent.button.y);
+ event.mouseButton.pos = WindowToInterfaceCoords(Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
}
else if (m_private->currentEvent.type == SDL_MOUSEMOTION)
{
event.type = EVENT_MOUSE_MOVE;
event.mouseMove.state = TranslatePressState(m_private->currentEvent.button.state);
- event.mouseMove.pos = WindowToInterfaceCoords(m_private->currentEvent.button.x, m_private->currentEvent.button.y);
+ event.mouseMove.pos = WindowToInterfaceCoords(Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
}
- // TODO: joystick state polling instead of getting events
else if (m_private->currentEvent.type == SDL_JOYAXISMOTION)
{
event.type = EVENT_JOY_AXIS;
@@ -569,16 +638,13 @@ void CApplication::ParseEvent()
event.joyButton.state = TranslatePressState(m_private->currentEvent.jbutton.state);
}
-
- if (m_robotMain != NULL && event.type != EVENT_NULL)
- {
- //m_robotMain->EventProcess(event);
- }
-
- ProcessEvent(event);
+ return event;
}
-void CApplication::ProcessEvent(Event event)
+/** Processes incoming events. It is the first function called after an event is captures.
+ Function returns \c true if the event is to be passed on to other processing functions
+ or \c false if not. */
+bool CApplication::ProcessEvent(const Event &event)
{
CLogger *l = GetLogger();
// Print the events in debug mode to test the code
@@ -621,8 +687,12 @@ void CApplication::ProcessEvent(Event event)
break;
}
}
+
+ // By default, pass on all events
+ return true;
}
+/** Renders the frame and swaps buffers as necessary. Returns \c false on error. */
bool CApplication::Render()
{
bool result = m_engine->Render();
@@ -709,14 +779,39 @@ int CApplication::GetKey(int keyRank, int option)
return 0;
}
-void CApplication::SetMousePos(Math::Point pos)
+void CApplication::SetGrabInput(bool grab)
{
- // TODO
+ SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF);
}
-void CApplication::SetMouseType(Gfx::MouseType type)
+bool CApplication::GetGrabInput()
{
- // TODO
+ int result = SDL_WM_GrabInput(SDL_GRAB_QUERY);
+ return result == SDL_GRAB_ON;
+}
+
+void CApplication::SetSystemMouseVisible(bool visible)
+{
+ SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
+}
+
+bool CApplication::GetSystemMouseVisibile()
+{
+ int result = SDL_ShowCursor(SDL_QUERY);
+ return result == SDL_ENABLE;
+}
+
+
+void CApplication::SetSystemMousePos(Math::Point pos)
+{
+ Math::IntPoint windowPos = InterfaceToWindowCoords(pos);
+ SDL_WarpMouse(windowPos.x, windowPos.y);
+ m_systemMousePos = pos;
+}
+
+Math::Point CApplication::GetSystemMousePos()
+{
+ return m_systemMousePos;
}
void CApplication::SetJoystickEnabled(bool enable)
@@ -766,3 +861,8 @@ void CApplication::OutputText(long x, long y, char* str)
{
// TODO
}
+
+std::string CApplication::GetDataFilePath(const std::string& dirName, const std::string& fileName)
+{
+ return m_dataPath + "/" + dirName + "/" + fileName;
+}
diff --git a/src/app/app.h b/src/app/app.h
index ed2bd9a..576ed62 100644
--- a/src/app/app.h
+++ b/src/app/app.h
@@ -21,6 +21,7 @@
#include "common/misc.h"
+#include "common/singleton.h"
#include "graphics/common/device.h"
#include "graphics/common/engine.h"
@@ -33,8 +34,8 @@ class CEvent;
class CRobotMain;
class CSound;
-struct ApplicationPrivate;
+struct ApplicationPrivate;
/**
* \class CApplication
@@ -67,7 +68,7 @@ struct ApplicationPrivate;
* The events are further handled in CRobotMain class.
*
*/
-class CApplication
+class CApplication : public CSingleton<CApplication>
{
public:
//! Constructor (can only be called once!)
@@ -75,13 +76,9 @@ public:
//! Destructor
~CApplication();
- //! Returns the only CApplication instance
- static CApplication* GetInstance()
- { return m_appInstance; }
-
public:
//! Parses commandline arguments
- Error ParseArguments(int argc, char *argv[]);
+ bool ParseArguments(int argc, char *argv[]);
//! Initializes the application
bool Create();
//! Main event loop
@@ -117,20 +114,31 @@ public:
void SetKey(int keyRank, int option, int key);
int GetKey(int keyRank, int option);
- void SetMouseType(Gfx::MouseType type);
- void SetMousePos(Math::Point pos);
+ //! Sets the grab mode for input (keyboard & mouse)
+ void SetGrabInput(bool grab);
+ //! Returns the grab mode
+ bool GetGrabInput();
+
+ //! Sets the visiblity of system mouse cursor
+ void SetSystemMouseVisible(bool visible);
+ //! Returns the visiblity of system mouse cursor
+ bool GetSystemMouseVisibile();
- //? void SetNiceMouse(bool nice);
- //? bool GetNiceMouse();
- //? bool GetNiceMouseCap();
+ //! Sets the position of system mouse cursor (in interface coords)
+ void SetSystemMousePos(Math::Point pos);
+ //! Returns the position of system mouse cursor (in interface coords)
+ Math::Point GetSystemMousePos();
bool WriteScreenShot(char *filename, int width, int height);
+ //! Returns the full path to a file in data directory
+ std::string GetDataFilePath(const std::string &dirName, const std::string &fileName);
+
protected:
- //! Processes an SDL event to Event struct
- void ParseEvent();
+ //! Processes the captured SDL event to Event struct
+ Event ParseEvent();
//! Handles some incoming events
- void ProcessEvent(Event event);
+ bool ProcessEvent(const Event &event);
//! Renders the image in window
bool Render();
@@ -140,16 +148,9 @@ protected:
void CloseJoystick();
//! Converts window coords to interface coords
- Math::Point WindowToInterfaceCoords(int x, int y);
-
- //HRESULT ConfirmDevice( DDCAPS* pddDriverCaps, D3DDEVICEDESC7* pd3dDeviceDesc );
- //HRESULT Initialize3DEnvironment();
- //HRESULT Change3DEnvironment();
- //HRESULT CreateZBuffer(GUID* pDeviceGUID);
- //HRESULT Render3DEnvironment();
- //VOID Cleanup3DEnvironment();
- //VOID DeleteDeviceObjects();
- //VOID DisplayFrameworkError( HRESULT, DWORD );
+ Math::Point WindowToInterfaceCoords(Math::IntPoint pos);
+ //! Converts the interface coords to window coords
+ Math::IntPoint InterfaceToWindowCoords(Math::Point pos);
void InitText();
void DrawSuppl();
@@ -157,8 +158,6 @@ protected:
void OutputText(long x, long y, char* str);
protected:
- //! The only instance of CApplication
- static CApplication* m_appInstance;
//! Instance manager
CInstanceManager* m_iMan;
//! Private (SDL-dependent data)
@@ -185,21 +184,16 @@ protected:
bool m_debugMode;
bool m_setupMode;
+ //! Whether joystick is enabled
bool m_joystickEnabled;
+ //! Text set as window title
std::string m_windowTitle;
- //? long m_vidMemTotal;
- //? bool m_appUseZBuffer;
- //? bool m_appUseStereo;
- //? bool m_audioState;
- //? bool m_audioTrack;
- //? bool m_niceMouse;
-
int m_keyState;
Math::Vector m_axeKey;
Math::Vector m_axeJoy;
- Math::Point m_mousePos;
+ Math::Point m_systemMousePos;
long m_mouseWheel;
//! Current state of joystick axes; may be updated from another thread
@@ -209,5 +203,8 @@ protected:
float m_time;
long m_key[50][2];
+
+ //! Path to directory with data files
+ std::string m_dataPath;
};
diff --git a/src/app/main.cpp b/src/app/main.cpp
index f857037..9eea6e4 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -69,10 +69,10 @@ int main(int argc, char *argv[])
CApplication app; // single instance of the application
- Error err = app.ParseArguments(argc, argv);
- if (err != ERR_OK)
+ if (! app.ParseArguments(argc, argv))
{
SystemDialog(SDT_ERROR, "COLOBOT", "Invalid commandline arguments!\n");
+ return app.GetExitCode();
}
int code = 0;
diff --git a/src/common/event.h b/src/common/event.h
index 70b110d..6ce1a79 100644
--- a/src/common/event.h
+++ b/src/common/event.h
@@ -36,6 +36,7 @@ enum EventType
// TODO: document the meaning of each value
+ //! Invalid event / no event
EVENT_NULL = 0,
//! Event sent on user or system quit request
@@ -638,6 +639,9 @@ struct Event
//! Type of event (EVENT_*)
EventType type;
+ //! If true, the event was produced by system (SDL); else, it has come from user interface
+ bool systemEvent;
+
//! Additional data for EVENT_KEY_DOWN and EVENT_KEY_UP
KeyEventData key;
//! Additional data for EVENT_MOUSE_BUTTON_DOWN and EVENT_MOUSE_BUTTON_UP
@@ -657,7 +661,8 @@ struct Event
//? short keyState; // state of the keyboard (KS_ *)
//? float rTime; // relative time
- Event(EventType aType = EVENT_NULL) : type(aType) {}
+ Event(EventType aType = EVENT_NULL)
+ : type(aType), systemEvent(false) {}
};
diff --git a/src/common/key.h b/src/common/key.h
index 0ed6b54..de31c09 100644
--- a/src/common/key.h
+++ b/src/common/key.h
@@ -27,8 +27,8 @@
// Key symbol defined as concatenation to SDLK_...
// If need arises, it can be changed to custom function or anything else
-#define KEY(x) SDLK_ # x
+#define KEY(x) SDLK_ ## x
// Key modifier defined as concatenation to KMOD_...
// If need arises, it can be changed to custom function or anything else
-#define KEY_MOD(x) KMOD_ # x
+#define KEY_MOD(x) KMOD_ ## x
diff --git a/src/common/singleton.h b/src/common/singleton.h
index ee01b24..4df7878 100644
--- a/src/common/singleton.h
+++ b/src/common/singleton.h
@@ -29,21 +29,21 @@ template<typename T> class CSingleton
public:
static T& GetInstance() {
- aserrt(mInstance);
+ assert(mInstance != NULL);
return *mInstance;
}
- static T& GetInstancePointer() {
- aserrt(mInstance);
+ static T* GetInstancePointer() {
+ assert(mInstance != NULL);
return mInstance;
}
static bool IsCreated() {
- return mInstance != NULL;
+ return mInstance != NULL;
}
CSingleton() {
- assert(!mInstance);
+ assert(mInstance == NULL);
mInstance = static_cast<T *>(this);
}
diff --git a/src/graphics/common/camera.h b/src/graphics/common/camera.h
index be52061..76077bf 100644
--- a/src/graphics/common/camera.h
+++ b/src/graphics/common/camera.h
@@ -141,7 +141,7 @@ class CCamera {
void SetCameraInvertY(bool bInvert);
float RetMotorTurn();
- Gfx::MouseType RetMouseDef(Math::Point pos);
+ Gfx::EngineMouseType RetMouseDef(Math::Point pos);
protected:
bool EventMouseMove(const Event &event);
diff --git a/src/graphics/common/color.h b/src/graphics/common/color.h
index 68421c7..907a3b9 100644
--- a/src/graphics/common/color.h
+++ b/src/graphics/common/color.h
@@ -36,12 +36,23 @@ struct Color
Color(float aR = 0.0f, float aG = 0.0f, float aB = 0.0f, float aA = 0.0f)
: r(aR), g(aG), b(aB), a(aA) {}
+ inline Gfx::Color Inverse() const
+ {
+ return Gfx::Color(1.0f - r, 1.0f - g, 1.0f - b, 1.0f - a);
+ }
+
//! Returns the struct cast to \c float* array; use with care!
inline float* Array()
{
return (float*)this;
}
+ //! Returns the struct cast to <tt>const float*</tt> array; use with care!
+ inline const float* Array() const
+ {
+ return (const float*)this;
+ }
+
//! Returns a string (r, g, b, a)
inline std::string ToString() const
{
@@ -50,6 +61,11 @@ struct Color
s << "(" << r << ", " << g << ", " << b << ", " << a << ")";
return s.str();
}
+
+ inline bool operator==(const Gfx::Color &other) const
+ {
+ return r == other.r && g == other.g && b == other.b && a == other.a;
+ }
};
/**
diff --git a/src/graphics/common/device.h b/src/graphics/common/device.h
index ceaf67a..d79d253 100644
--- a/src/graphics/common/device.h
+++ b/src/graphics/common/device.h
@@ -90,6 +90,7 @@ enum RenderState
RENDER_STATE_DEPTH_TEST,
RENDER_STATE_DEPTH_WRITE,
RENDER_STATE_ALPHA_TEST,
+ RENDER_STATE_CULLING,
RENDER_STATE_DITHERING
};
@@ -292,14 +293,14 @@ public:
virtual void MultiplyTransform(TransformType type, const Math::Matrix &matrix) = 0;
//! Sets the current material
- virtual void SetMaterial(Gfx::Material &material) = 0;
+ virtual void SetMaterial(const Gfx::Material &material) = 0;
//! Returns the current material
virtual const Gfx::Material& GetMaterial() = 0;
//! Returns the maximum number of lights available
virtual int GetMaxLightCount() = 0;
//! Sets the light at given index
- virtual void SetLight(int index, Gfx::Light &light) = 0;
+ virtual void SetLight(int index, const Gfx::Light &light) = 0;
//! Returns the current light at given index
virtual const Gfx::Light& GetLight(int index) = 0;
//! Enables/disables the light at given index
@@ -308,18 +309,18 @@ public:
virtual bool GetLightEnabled(int index) = 0;
//! Creates a texture from image; the image can be safely removed after that
- virtual Gfx::Texture* CreateTexture(CImage *image, const Gfx::TextureCreateParams &params) = 0;
+ virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams &params) = 0;
//! Deletes a given texture, freeing it from video memory
- virtual void DestroyTexture(Gfx::Texture *texture) = 0;
+ virtual void DestroyTexture(const Gfx::Texture &texture) = 0;
//! Deletes all textures created so far
virtual void DestroyAllTextures() = 0;
//! Returns the maximum number of multitexture stages
virtual int GetMaxTextureCount() = 0;
//! Sets the (multi)texture at given index
- virtual void SetTexture(int index, Gfx::Texture *texture) = 0;
+ virtual void SetTexture(int index, const Gfx::Texture &texture) = 0;
//! Returns the (multi)texture at given index
- virtual Gfx::Texture* GetTexture(int index) = 0;
+ virtual Gfx::Texture GetTexture(int index) = 0;
//! Enables/disables the given texture stage
virtual void SetTextureEnabled(int index, bool enabled) = 0;
//! Returns the current enable state of given texture stage
@@ -331,7 +332,7 @@ public:
virtual Gfx::TextureParams GetTextureParams(int index) = 0;
//! Sets the texture factor to the given color value
- virtual void SetTextureFactor(Gfx::Color &color) = 0;
+ virtual void SetTextureFactor(const Gfx::Color &color) = 0;
//! Returns the current texture factor
virtual Gfx::Color GetTextureFactor() = 0;
@@ -343,7 +344,7 @@ public:
virtual void DrawPrimitive(Gfx::PrimitiveType type, Gfx::VertexTex2 *vertices, int vertexCount) = 0;
//! Tests whether a sphere intersects the 6 clipping planes of projection volume
- virtual int ComputeSphereVisibility(Math::Vector center, float radius) = 0;
+ virtual int ComputeSphereVisibility(const Math::Vector &center, float radius) = 0;
//! Enables/disables the given render state
virtual void SetRenderState(Gfx::RenderState state, bool enabled) = 0;
@@ -371,17 +372,17 @@ public:
virtual void GetBlendFunc(Gfx::BlendFunc &srcBlend, Gfx::BlendFunc &dstBlend) = 0;
//! Sets the clear color
- virtual void SetClearColor(Gfx::Color color) = 0;
+ virtual void SetClearColor(const Gfx::Color &color) = 0;
//! Returns the current clear color
virtual Gfx::Color GetClearColor() = 0;
//! Sets the global ambient color
- virtual void SetGlobalAmbient(Gfx::Color color) = 0;
+ virtual void SetGlobalAmbient(const Gfx::Color &color) = 0;
//! Returns the global ambient color
virtual Gfx::Color GetGlobalAmbient() = 0;
//! Sets the fog parameters: mode, color, start distance, end distance and density (for exp models)
- virtual void SetFogParams(Gfx::FogMode mode, Gfx::Color color, float start, float end, float density) = 0;
+ virtual void SetFogParams(Gfx::FogMode mode, const Gfx::Color &color, float start, float end, float density) = 0;
//! Returns the current fog parameters: mode, color, start distance, end distance and density (for exp models)
virtual void GetFogParams(Gfx::FogMode &mode, Gfx::Color &color, float &start, float &end, float &density) = 0;
diff --git a/src/graphics/common/engine.cpp b/src/graphics/common/engine.cpp
index 0b92224..c474402 100644
--- a/src/graphics/common/engine.cpp
+++ b/src/graphics/common/engine.cpp
@@ -19,9 +19,24 @@
#include "graphics/common/engine.h"
+#include "app/app.h"
+#include "common/iman.h"
+#include "common/image.h"
+#include "common/key.h"
#include "graphics/common/device.h"
#include "math/geometry.h"
+// Initial size of various vectors
+const int OBJECT_PREALLOCATE_COUNT = 1200;
+const int SHADOW_PREALLOCATE_COUNT = 500;
+const int GROUNDSPOT_PREALLOCATE_COUNT = 100;
+
+const int LEVEL1_PREALLOCATE_COUNT = 50;
+const int LEVEL2_PREALLOCATE_COUNT = 100;
+const int LEVEL3_PREALLOCATE_COUNT = 5;
+const int LEVEL4_PREALLOCATE_COUNT = 10;
+const int LEVEL5_PREALLOCATE_COUNT = 100;
+const int LEVEL5_VERTEX_PREALLOCATE_COUNT = 200;
Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
@@ -32,7 +47,117 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
m_wasInit = false;
- // TODO
+ m_iMan = iMan;
+ m_iMan->AddInstance(CLASS_ENGINE, this);
+ m_app = app;
+
+ /*m_light = new Gfx::CLight(m_iMan, this);
+ m_text = new Gfx::CText(m_iMan, this);
+ m_particle = new Gfx::CParticle(m_iMan, this);
+ m_water = new Gfx::CWater(m_iMan, this);
+ m_cloud = new Gfx::CCloud(m_iMan, this);
+ m_lightning = new Gfx::CLightning(m_iMan, this);
+ m_planet = new Gfx::CPlanet(m_iMan, this);*/
+ m_sound = NULL;
+ m_terrain = NULL;
+
+ m_dim.x = 640;
+ m_dim.y = 480;
+ m_lastDim = m_dim;
+ m_focus = 0.75f;
+ m_baseTime = 0;
+ m_lastTime = 0;
+ m_absTime = 0.0f;
+ m_rankView = 0;
+
+ m_ambientColor[0] = Gfx::Color(0.5f, 0.5f, 0.5f, 0.5f);
+ m_ambientColor[1] = Gfx::Color(0.5f, 0.5f, 0.5f, 0.5f);
+ m_fogColor[0] = Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f);
+ m_fogColor[1] = Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f);
+ m_deepView[0] = 1000.0f;
+ m_deepView[1] = 1000.0f;
+ m_fogStart[0] = 0.75f;
+ m_fogStart[1] = 0.75f;
+ m_waterAddColor = Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f);
+
+ m_pause = false;
+ m_render = true;
+ m_movieLock = false;
+ m_shadowVisible = true;
+ m_groundSpotVisible = true;
+ m_dirty = true;
+ m_fog = true;
+ m_speed = 1.0f;
+ m_secondTexNum = 0;
+ m_eyeDirH = 0.0f;
+ m_eyeDirV = 0.0f;
+ m_backgroundName = ""; // no background image
+ m_backgroundColorUp = 0;
+ m_backgroundColorDown = 0;
+ m_backgroundCloudUp = 0;
+ m_backgroundCloudDown = 0;
+ m_backgroundFull = false;
+ m_backgroundQuarter = false;
+ m_overFront = true;
+ m_overColor = 0;
+ m_overMode = ENG_RSTATE_TCOLOR_BLACK;
+ m_frontsizeName = ""; // no front image
+ m_hiliteRank[0] = -1; // empty list
+ m_eyePt = Math::Vector(0.0f, 0.0f, 0.0f);
+ m_lookatPt = Math::Vector(0.0f, 0.0f, 1.0f);
+ m_drawWorld = true;
+ m_drawFront = false;
+ m_limitLOD[0] = 100.0f;
+ m_limitLOD[1] = 200.0f;
+ m_particuleDensity = 1.0f;
+ m_clippingDistance = 1.0f;
+ m_lastClippingDistance = m_clippingDistance;
+ m_objectDetail = 1.0f;
+ m_lastObjectDetail = m_objectDetail;
+ m_terrainVision = 1000.0f;
+ m_gadgetQuantity = 1.0f;
+ m_textureQuality = 1;
+ m_totoMode = true;
+ m_lensMode = true;
+ m_waterMode = true;
+ m_skyMode = true;
+ m_backForce = true;
+ m_planetMode = true;
+ m_lightMode = true;
+ m_editIndentMode = true;
+ m_editIndentValue = 4;
+ m_tracePrecision = 1.0f;
+
+ m_alphaMode = 1;
+
+ m_forceStateColor = true;
+ m_stateColor = false;
+
+ m_blackSrcBlend[0] = 0;
+ m_blackDestBlend[0] = 0;
+ m_whiteSrcBlend[0] = 0;
+ m_whiteDestBlend[0] = 0;
+ m_diffuseSrcBlend[0] = 0;
+ m_diffuseDestBlend[0] = 0;
+ m_alphaSrcBlend[0] = 0;
+ m_alphaDestBlend[0] = 0;
+
+ m_updateGeometry = false;
+
+ m_mousePos = Math::Point(0.5f, 0.5f);
+ m_mouseType = Gfx::ENG_MOUSE_NORM;
+ m_mouseVisible = false;
+
+ m_texPath = "textures/";
+ m_defaultTexParams.format = Gfx::TEX_IMG_RGBA;
+ m_defaultTexParams.mipmap = true;
+ m_defaultTexParams.minFilter = Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR;
+ m_defaultTexParams.magFilter = Gfx::TEX_MAG_FILTER_LINEAR;
+
+ m_objectTree.reserve(LEVEL1_PREALLOCATE_COUNT);
+ m_objects.reserve(OBJECT_PREALLOCATE_COUNT);
+ m_shadow.reserve(SHADOW_PREALLOCATE_COUNT);
+ m_groundSpot.reserve(GROUNDSPOT_PREALLOCATE_COUNT);
}
Gfx::CEngine::~CEngine()
@@ -41,7 +166,29 @@ Gfx::CEngine::~CEngine()
m_app = NULL;
m_device = NULL;
- // TODO
+ /*delete m_light;
+ m_light = NULL;
+
+ delete m_text;
+ m_text = NULL;
+
+ delete m_particle;
+ m_particle = NULL;
+
+ delete m_water;
+ m_water = NULL;
+
+ delete m_cloud;
+ m_cloud = NULL;
+
+ delete m_lightning;
+ m_lightning = NULL;
+
+ delete m_planet;
+ m_planet = NULL;*/
+
+ m_sound = NULL;
+ m_terrain = NULL;
}
bool Gfx::CEngine::GetWasInit()
@@ -64,7 +211,9 @@ bool Gfx::CEngine::Create()
{
m_wasInit = true;
- // TODO
+ m_matWorldInterface.LoadIdentity();
+ m_matViewInterface.LoadIdentity();
+ Math::LoadOrthoProjectionMatrix(m_matProjInterface, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
return true;
}
@@ -90,39 +239,502 @@ bool Gfx::CEngine::AfterDeviceSetInit()
{
m_device->SetClearColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f));
- // TODO
+ m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false);
+
+ Gfx::TextureCreateParams params;
+ params.format = Gfx::TEX_IMG_RGB;
+ params.minFilter = Gfx::TEX_MIN_FILTER_NEAREST;
+ params.magFilter = Gfx::TEX_MAG_FILTER_NEAREST;
+ params.mipmap = false;
+ CreateTexture("mouse.png", params);
return true;
}
+bool Gfx::CEngine::ProcessEvent(const Event &event)
+{
+ if (event.type == EVENT_MOUSE_MOVE)
+ {
+ m_mousePos = event.mouseMove.pos;
+ }
+ else if (event.type == EVENT_KEY_DOWN)
+ {
+ // !! Debug, to be removed later !!
+
+ if (event.key.key == KEY(F1))
+ {
+ m_mouseVisible = !m_mouseVisible;
+ m_app->SetSystemMouseVisible(! m_app->GetSystemMouseVisibile());
+ }
+ else if (event.key.key == KEY(F2))
+ {
+ int index = (int)m_mouseType;
+ m_mouseType = (Gfx::EngineMouseType)( (index + 1) % Gfx::ENG_MOUSE_COUNT );
+ }
+ }
+
+ // By default, pass on all events
+ return true;
+}
+
+void Gfx::CEngine::SetTexture(const std::string &name, int stage)
+{
+ std::map<std::string, Gfx::Texture>::iterator it = m_texNameMap.find(name);
+ if (it != m_texNameMap.end())
+ m_device->SetTexture(stage, (*it).second);
+
+ // TODO if not present...
+}
+
+void Gfx::CEngine::SetMaterial(const Gfx::Material &mat)
+{
+ m_device->SetMaterial(mat);
+}
+
+void Gfx::CEngine::SetState(int state, Gfx::Color color)
+{
+ if ( state == m_lastState && color == m_lastColor )
+ return;
+
+ m_lastState = state;
+ m_lastColor = color;
+
+ if ( m_alphaMode != 1 && (state & Gfx::ENG_RSTATE_ALPHA) )
+ {
+ state &= ~Gfx::ENG_RSTATE_ALPHA;
+
+ if (m_alphaMode == 2)
+ state |= Gfx::ENG_RSTATE_TTEXTURE_BLACK;
+ }
+
+ if (state & Gfx::ENG_RSTATE_TTEXTURE_BLACK) // The transparent black texture?
+ {
+ m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false);
+ m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false);
+ m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true);
+ m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false);
+
+ m_device->SetBlendFunc(Gfx::BLEND_ONE, Gfx::BLEND_INV_SRC_COLOR);
+
+ m_device->SetTextureFactor(color);
+
+ Gfx::TextureParams params;
+ params.colorOperation = Gfx::TEX_MIX_OPER_MODULATE;
+ params.colorArg1 = Gfx::TEX_MIX_ARG_TEXTURE;
+ params.colorArg2 = Gfx::TEX_MIX_ARG_FACTOR;
+ // TODO: params.alphaOperation = Gfx::TEX_MIX_OPER_DISABLED;
+ m_device->SetTextureParams(0, params);
+ }
+ else if (state & Gfx::ENG_RSTATE_TTEXTURE_WHITE) // The transparent white texture?
+ {
+ m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false);
+ m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false);
+ m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true);
+ m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false);
+
+ m_device->SetBlendFunc(Gfx::BLEND_DST_COLOR, Gfx::BLEND_ZERO);
+
+ m_device->SetTextureFactor(color.Inverse());
+
+ Gfx::TextureParams params;
+ params.colorOperation = Gfx::TEX_MIX_OPER_ADD;
+ params.colorArg1 = Gfx::TEX_MIX_ARG_TEXTURE;
+ params.colorArg2 = Gfx::TEX_MIX_ARG_FACTOR;
+ // TODO: params.alphaOperation = Gfx::TEX_MIX_OPER_DISABLED;
+ m_device->SetTextureParams(0, params);
+ }
+ // TODO other modes
+ else if (state & Gfx::ENG_RSTATE_TCOLOR_BLACK) // The transparent black color?
+ {
+ /*
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_blackSrcBlend[1]);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_blackDestBlend[1]);
+
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);*/
+ }
+ else if (state & Gfx::ENG_RSTATE_TCOLOR_WHITE) // The transparent white color?
+ {
+ /*m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_whiteSrcBlend[1]);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_whiteDestBlend[1]);
+
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, ~color);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);*/
+ }
+ else if (state & Gfx::ENG_RSTATE_TDIFFUSE) // diffuse color as transparent?
+ {
+ /*m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_diffuseSrcBlend[1]);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_diffuseDestBlend[1]);
+
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);*/
+ }
+ else if (state & Gfx::ENG_RSTATE_ALPHA) // image with alpha channel?
+ {
+ /*m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, true);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, true);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATER);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAREF, (DWORD)(128));
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_alphaSrcBlend[1]);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_alphaSrcBlend[1]);
+
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);*/
+ }
+ else // normal ?
+ {
+ /*m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, true);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, false);
+ m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false);
+
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
+ m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);*/
+ }
+
+ if (state & Gfx::ENG_RSTATE_FOG)
+ m_device->SetRenderState(Gfx::RENDER_STATE_FOG, true);
+
+
+ bool second = m_groundSpotVisible || m_dirty;
+
+ if ( !m_groundSpotVisible && (state & Gfx::ENG_RSTATE_SECOND) != 0 ) second = false;
+ if ( !m_dirty && (state & Gfx::ENG_RSTATE_SECOND) == 0 ) second = false;
+
+ if ( (state & ENG_RSTATE_DUAL_BLACK) && second )
+ {
+ /*m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);*/
+ }
+ else if ( (state & ENG_RSTATE_DUAL_WHITE) && second )
+ {
+ /*m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);*/
+ }
+ else
+ {
+ /*m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);*/
+ }
+
+ if (state & Gfx::ENG_RSTATE_WRAP)
+ {
+ /*m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_WRAP);*/
+ }
+ else if (state & Gfx::ENG_RSTATE_CLAMP)
+ {
+ /*m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);*/
+ }
+ else
+ {
+ /*m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
+ m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);*/
+ }
+
+ if (state & Gfx::ENG_RSTATE_2FACE)
+ {
+ m_device->SetRenderState(Gfx::RENDER_STATE_CULLING, false);
+ }
+ else
+ {
+ m_device->SetRenderState(Gfx::RENDER_STATE_CULLING, true);
+ m_device->SetCullMode(Gfx::CULL_CCW);
+ }
+
+ if (state & Gfx::ENG_RSTATE_LIGHT)
+ m_device->SetGlobalAmbient(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f));
+ else
+ m_device->SetGlobalAmbient(m_ambientColor[m_rankView]);
+}
+
bool Gfx::CEngine::Render()
{
+ m_statisticTriangle = 0;
+
m_device->BeginScene();
- Math::Matrix world;
- world.LoadIdentity();
- m_device->SetTransform(Gfx::TRANSFORM_WORLD, world);
+ SetUp3DView();
+
+ if (! Draw3DScene() )
+ return false;
+
+ SetUpInterfaceView();
+
+ if (! DrawInterface() )
+ return false;
+
+ m_device->EndScene();
+
+ return true;
+}
- Math::Matrix view;
- view.LoadIdentity();
- m_device->SetTransform(Gfx::TRANSFORM_VIEW, view);
+void Gfx::CEngine::SetUp3DView()
+{
+ // TODO
+}
- Math::Matrix proj;
- Math::LoadOrthoProjectionMatrix(proj, -10.0f, 10.0f, -10.0f, 10.0f);
- m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, proj);
+bool Gfx::CEngine::Draw3DScene()
+{
+ // TODO
+ return true;
+}
+void Gfx::CEngine::SetUpInterfaceView()
+{
+ m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_matWorldInterface);
+ m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface);
+ m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface);
+}
+
+bool Gfx::CEngine::DrawInterface()
+{
Gfx::VertexCol vertices[3] =
{
- Gfx::VertexCol(Math::Vector(-2.0f, -1.0f, 0.0f), Gfx::Color(1.0f, 0.0f, 0.0f)),
- Gfx::VertexCol(Math::Vector( 2.0f, -1.0f, 0.0f), Gfx::Color(0.0f, 1.0f, 0.0f)),
- Gfx::VertexCol(Math::Vector( 0.0f, 1.5f, 0.0f), Gfx::Color(0.0f, 0.0f, 1.0f))
+ Gfx::VertexCol(Math::Vector( 0.25f, 0.25f, 0.0f), Gfx::Color(1.0f, 0.0f, 0.0f)),
+ Gfx::VertexCol(Math::Vector( 0.75f, 0.25f, 0.0f), Gfx::Color(0.0f, 1.0f, 0.0f)),
+ Gfx::VertexCol(Math::Vector( 0.5f, 0.75f, 0.0f), Gfx::Color(0.0f, 0.0f, 1.0f))
};
m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, vertices, 3);
- m_device->EndScene();
+ DrawMouse();
return true;
}
+void Gfx::CEngine::DrawMouse()
+{
+ struct EngineMouse
+ {
+ Gfx::EngineMouseType type;
+ int icon1;
+ int icon2;
+ int iconShadow;
+ Gfx::EngineRenderState mode1;
+ Gfx::EngineRenderState mode2;
+ Math::Point hotPoint;
+
+ EngineMouse(Gfx::EngineMouseType = Gfx::ENG_MOUSE_NORM,
+ int icon1 = -1, int icon2 = -1, int iconShadow = -1,
+ Gfx::EngineRenderState mode1 = Gfx::ENG_RSTATE_NORMAL,
+ Gfx::EngineRenderState mode2 = ENG_RSTATE_NORMAL,
+ Math::Point hotPoint = Math::Point())
+ {
+ this->type = type;
+ this->icon1 = icon1;
+ this->icon2 = icon2;
+ this->iconShadow = iconShadow;
+ this->mode1 = mode1;
+ this->mode2 = mode2;
+ this->hotPoint = hotPoint;
+ }
+ };
+
+ static const EngineMouse MICE[Gfx::ENG_MOUSE_COUNT] =
+ {
+ EngineMouse(Gfx::ENG_MOUSE_NORM, 0, 1, 32, Gfx::ENG_RSTATE_TCOLOR_WHITE, Gfx::ENG_RSTATE_TCOLOR_BLACK, Math::Point( 1.0f, 1.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_WAIT, 2, 3, 33, Gfx::ENG_RSTATE_TCOLOR_WHITE, Gfx::ENG_RSTATE_TCOLOR_BLACK, Math::Point( 8.0f, 12.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_HAND, 4, 5, 34, Gfx::ENG_RSTATE_TCOLOR_WHITE, Gfx::ENG_RSTATE_TCOLOR_BLACK, Math::Point( 7.0f, 2.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_NO, 6, 7, 35, Gfx::ENG_RSTATE_TCOLOR_WHITE, Gfx::ENG_RSTATE_TCOLOR_BLACK, Math::Point(10.0f, 10.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_EDIT, 8, 9, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 6.0f, 10.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_CROSS, 10, 11, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point(10.0f, 10.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_MOVEV, 12, 13, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 5.0f, 11.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_MOVEH, 14, 15, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point(11.0f, 5.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_MOVED, 16, 17, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 9.0f, 9.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_MOVEI, 18, 19, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 9.0f, 9.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_MOVE, 20, 21, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point(11.0f, 11.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_TARGET, 22, 23, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point(15.0f, 15.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_SCROLLL, 24, 25, 43, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 2.0f, 9.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_SCROLLR, 26, 27, 44, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point(17.0f, 9.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_SCROLLU, 28, 29, 45, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 9.0f, 2.0f)),
+ EngineMouse(Gfx::ENG_MOUSE_SCROLLD, 30, 31, 46, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 9.0f, 17.0f))
+ };
+
+ static const Math::Point MOUSE_SIZE(0.05f, 0.05f);
+
+ if (! m_mouseVisible)
+ return;
+
+ if (m_app->GetSystemMouseVisibile())
+ return;
+
+
+ Gfx::Material material;
+ material.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f);
+ material.ambient = Gfx::Color(0.5f, 0.5f, 0.5f);
+
+ SetMaterial(material);
+ SetTexture("mouse.png");
+
+ for (int i = 0; i < Gfx::ENG_MOUSE_COUNT; ++i)
+ {
+ if (m_mouseType != MICE[i].type)
+ continue;
+
+ Math::Point pos;
+ pos.x = m_mousePos.x - (MICE[i].hotPoint.x * MOUSE_SIZE.x) / 32.0f;
+ pos.y = m_mousePos.y - ((32.0f - MICE[i].hotPoint.y) * MOUSE_SIZE.y) / 32.0f;
+
+ Math::Point shadowPos;
+ shadowPos.x = pos.x+(4.0f/640.0f);
+ shadowPos.y = pos.y-(3.0f/480.0f);
+
+ // FIXME: doesn't work yet
+
+ SetState(Gfx::ENG_RSTATE_TCOLOR_WHITE);
+ DrawMouseSprite(shadowPos, MOUSE_SIZE, MICE[i].iconShadow);
+
+ SetState(MICE[i].mode1);
+ DrawMouseSprite(pos, MOUSE_SIZE, MICE[i].icon1);
+
+ SetState(MICE[i].mode2);
+ DrawMouseSprite(pos, MOUSE_SIZE, MICE[i].icon2);
+
+ break;
+ }
+}
+
+void Gfx::CEngine::DrawMouseSprite(Math::Point pos, Math::Point size, int icon)
+{
+ if (icon == -1)
+ return;
+
+ Math::Point p1 = pos;
+ Math::Point p2 = p1 + size;
+
+ float u1 = (32.0f / 256.0f) * (icon % 8);
+ float v1 = (32.0f / 256.0f) * (icon / 8);
+ float u2 = (32.0f / 256.0f) + u1;
+ float v2 = (32.0f / 256.0f) + v1;
+
+ float dp = 0.5f / 256.0f;
+ u1 += dp;
+ v1 += dp;
+ u2 -= dp;
+ v2 -= dp;
+
+ Math::Vector normal(0.0f, 0.0f, -1.0f);
+
+ Gfx::Vertex vertex[4] =
+ {
+ Gfx::Vertex(Math::Vector(p1.x, p1.y, 0.0f), normal, Math::Point(u1, v2)),
+ Gfx::Vertex(Math::Vector(p1.x, p2.y, 0.0f), normal, Math::Point(u1, v1)),
+ Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), normal, Math::Point(u2, v2)),
+ Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), normal, Math::Point(u2, v1))
+ };
+
+ m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
+ AddStatisticTriangle(2);
+}
+
+Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName, const Gfx::TextureCreateParams &params)
+{
+ CImage img;
+ if (! img.Load(m_app->GetDataFilePath(m_texPath, texName)))
+ {
+ std::stringstream str;
+ str << "Couldn't load texture '" << texName << "': " << img.GetError();
+ m_error = str.str();
+ return Gfx::Texture(); // invalid texture
+ }
+
+ Gfx::Texture result = m_device->CreateTexture(&img, params);
+
+ if (! result.valid)
+ {
+ std::stringstream str;
+ str << "Couldn't load texture '" << texName << "': " << m_device->GetError();
+ m_error = str.str();
+ return result;
+ }
+ m_texNameMap[texName] = result;
+ m_revTexNameMap[result] = texName;
+
+ return result;
+}
+
+Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName)
+{
+ return CreateTexture(texName, m_defaultTexParams);
+}
+
+void Gfx::CEngine::DestroyTexture(const std::string &texName)
+{
+ std::map<std::string, Gfx::Texture>::iterator it = m_texNameMap.find(texName);
+ if (it == m_texNameMap.end())
+ return;
+
+ std::map<Gfx::Texture, std::string>::iterator revIt = m_revTexNameMap.find((*it).second);
+
+ m_device->DestroyTexture((*it).second);
+
+ m_revTexNameMap.erase(revIt);
+ m_texNameMap.erase(it);
+}
+
+void Gfx::CEngine::SetMouseVisible(bool visible)
+{
+ m_mouseVisible = visible;
+}
+
+bool Gfx::CEngine::GetMouseVisible()
+{
+ return m_mouseVisible;
+}
+
+void Gfx::CEngine::SetMousePos(Math::Point pos)
+{
+ m_mousePos = pos;
+}
+
+Math::Point Gfx::CEngine::GetMousePos()
+{
+ return m_mousePos;
+}
+
+void Gfx::CEngine::SetMouseType(Gfx::EngineMouseType type)
+{
+ m_mouseType = type;
+}
+
+Gfx::EngineMouseType Gfx::CEngine::GetMouseType()
+{
+ return m_mouseType;
+}
+
+void Gfx::CEngine::AddStatisticTriangle(int count)
+{
+ m_statisticTriangle += count;
+}
diff --git a/src/graphics/common/engine.h b/src/graphics/common/engine.h
index 735d72a..b1510fd 100644
--- a/src/graphics/common/engine.h
+++ b/src/graphics/common/engine.h
@@ -20,8 +20,10 @@
#pragma once
+#include "common/event.h"
#include "graphics/common/color.h"
#include "graphics/common/material.h"
+#include "graphics/common/texture.h"
#include "graphics/common/vertex.h"
#include "math/intpoint.h"
#include "math/matrix.h"
@@ -30,6 +32,8 @@
#include <string>
+#include <vector>
+#include <map>
class CApplication;
@@ -51,75 +55,317 @@ class CPlanet;
class CTerrain;
-//const int MAXOBJECT = 1200;
-//const int MAXSHADOW = 500;
-//const int MAXGROUNDSPOT = 100;
+/**
+ \enum EngineTriangleType
+ \brief Type of triangles drawn for engine objects */
+enum EngineTriangleType
+{
+ //! Triangles
+ ENG_TRIANGLE_TYPE_6T = 1,
+ //! Surfaces
+ ENG_TRIANGLE_TYPE_6S = 2
+};
+/**
+ \struct EngineTriangle
+ \brief A triangle drawn by the graphics engine */
+struct EngineTriangle
+{
+ //! Triangle vertices
+ Gfx::VertexTex2 triangle[3];
+ //! Material
+ Gfx::Material material;
+ //! Render state (TODO: ?)
+ int state;
+ //! 1st texture
+ Gfx::Texture tex1;
+ //! 2nd texture
+ Gfx::Texture tex2;
+
+ EngineTriangle()
+ {
+ state = 0;
+ }
+};
-enum ObjectType
+/**
+ \enum EngineObjectType
+ \brief Class of graphics engine object */
+enum EngineObjectType
{
//! Object doesn't exist
- OBJTYPE_NULL = 0,
+ ENG_OBJTYPE_NULL = 0,
//! Terrain
- OBJTYPE_TERRAIN = 1,
+ ENG_OBJTYPE_TERRAIN = 1,
//! Fixed object
- OBJTYPE_FIX = 2,
+ ENG_OBJTYPE_FIX = 2,
//! Moving object
- OBJTYPE_VEHICULE = 3,
+ ENG_OBJTYPE_VEHICULE = 3,
//! Part of a moving object
- OBJTYPE_DESCENDANT = 4,
+ ENG_OBJTYPE_DESCENDANT = 4,
//! Fixed object type quartz
- OBJTYPE_QUARTZ = 5,
+ ENG_OBJTYPE_QUARTZ = 5,
//! Fixed object type metal
- OBJTYPE_METAL = 6
+ ENG_OBJTYPE_METAL = 6
+};
+
+/**
+ \struct EngineObject
+ \brief Object drawn by the graphics engine */
+struct EngineObject
+{
+ //! If true, the object is drawn
+ bool visible;
+ //! If true, object is behind the 2D interface
+ bool drawWorld;
+ //! If true, the shape is before the 2D interface
+ bool drawFront;
+ //! Number of triangles
+ int totalTriangles;
+ //! Type of object
+ Gfx::EngineObjectType type;
+ //! Transformation matrix
+ Math::Matrix transform;
+ //! Distance view - origin (TODO: ?)
+ float distance;
+ //! Bounding box min (origin 0,0,0 always included)
+ Math::Vector bboxMin;
+ //! bounding box max (origin 0,0,0 always included)
+ Math::Vector bboxMax;
+ //! Radius of the sphere at the origin
+ float radius;
+ //! Rank of the associated shadow
+ int shadowRank;
+ //! Transparency of the object [0, 1]
+ float transparency;
+
+ EngineObject()
+ {
+ visible = false;
+ drawWorld = false;
+ drawFront = false;
+ totalTriangles = 0;
+ distance = 0.0f;
+ radius = 0.0f;
+ shadowRank = 0;
+ transparency = 0.0f;
+ }
+};
+
+struct EngineObjLevel1;
+struct EngineObjLevel2;
+struct EngineObjLevel3;
+struct EngineObjLevel4;
+struct EngineObjLevel5;
+
+/**
+ \struct EngineObjLevel5
+ \brief Tier 5 of object tree */
+struct EngineObjLevel5
+{
+ Gfx::Material material;
+ int state;
+ Gfx::EngineTriangleType type;
+ std::vector<Gfx::VertexTex2> vertices;
+
+ EngineObjLevel5();
+};
+
+/**
+ \struct EngineObjLevel4
+ \brief Tier 4 of object tree */
+struct EngineObjLevel4
+{
+ int reserved;
+ std::vector<Gfx::EngineObjLevel5> up;
+ Gfx::EngineObjLevel3* down;
+
+ EngineObjLevel4();
+};
+
+/**
+ \struct EngineObjLevel3
+ \brief Tier 3 of object tree */
+struct EngineObjLevel3
+{
+ float min;
+ float max;
+ std::vector<Gfx::EngineObjLevel4> up;
+ Gfx::EngineObjLevel2* down;
+
+ EngineObjLevel3();
+};
+
+/**
+ \struct EngineObjLevel2
+ \brief Tier 2 of object tree */
+struct EngineObjLevel2
+{
+ int objRank;
+ std::vector<Gfx::EngineObjLevel3> up;
+ Gfx::EngineObjLevel1* down;
+
+ EngineObjLevel2();
+};
+
+/**
+ \struct EngineObjLevel1
+ \brief Tier 1 of object tree */
+struct EngineObjLevel1
+{
+ Gfx::Texture tex1;
+ Gfx::Texture tex2;
+ std::vector<Gfx::EngineObjLevel2> up;
+
+ EngineObjLevel1();
+};
+
+/**
+ \struct EngineShadowType
+ \brief Type of shadow drawn by the graphics engine */
+enum EngineShadowType
+{
+ //! Normal shadow
+ ENG_SHADOW_NORM = 0,
+ //! TODO: ?
+ ENG_SHADOW_WORM = 1
+};
+
+/**
+ \struct EngineShadow
+ \brief Shadow drawn by the graphics engine */
+struct EngineShadow
+{
+ //! If true, shadow is invisible (object being carried for example)
+ bool hide;
+ //! Rank of the associated object
+ int objRank;
+ //! Type of shadow
+ Gfx::EngineShadowType type;
+ //! Position of the shadow
+ Math::Vector pos;
+ //! Normal to the terrain
+ Math::Vector normal;
+ //! Angle of the shadow
+ float angle;
+ //! Radius of the shadow
+ float radius;
+ //! Intensity of the shadow
+ float intensity;
+ //! Height from the ground
+ float height;
+
+ EngineShadow()
+ {
+ hide = false;
+ objRank = 0;
+ angle = radius = intensity = height = 0.0f;
+ }
};
-enum TriangleType
+/**
+ \struct EngineGroundSpot
+ \brief A spot (large shadow) drawn on the ground by the graphics engine */
+struct EngineGroundSpot
{
- //! triangles
- TRIANGLE_TYPE_6T = 1,
- //! surfaces
- TRIANGLE_TYPE_6S = 2
+ //! Color of the shadow
+ Gfx::Color color;
+ //! Min altitude
+ float min;
+ //! Max altitude
+ float max;
+ //! Transition area
+ float smooth;
+ //! Position for the shadow
+ Math::Vector pos;
+ //! Radius of the shadow
+ float radius;
+ //! Position of the shadow drawn
+ Math::Vector drawPos;
+ //! Radius of the shadow drawn
+ float drawRadius;
+
+ EngineGroundSpot()
+ {
+ min = max = smooth = radius = drawRadius = 0.0f;
+ }
};
-enum Mapping
+/**
+ \enum EngineGroundMarkPhase
+ \brief Phase of life of an EngineGroundMark */
+enum EngineGroundMarkPhase
{
- MAPPING_X = 1,
- MAPPING_Y = 2,
- MAPPING_Z = 3,
- MAPPING_1X = 4,
- MAPPING_1Y = 5,
- MAPPING_1Z = 6
+ //! Increase
+ ENG_GR_MARK_PHASE_INC = 1,
+ //! Fixed
+ ENG_GR_MARK_PHASE_FIX = 2,
+ //! Decrease
+ ENG_GR_MARK_PHASE_DEC = 2
};
-enum MouseType
+/**
+ \struct EngineGroundMark
+ \brief A mark on ground drawn by the graphics engine */
+struct EngineGroundMark
{
- MOUSE_HIDE = 0, // no mouse
- MOUSE_NORM = 1,
- MOUSE_WAIT = 2,
- MOUSE_EDIT = 3,
- MOUSE_HAND = 4,
- MOUSE_CROSS = 5,
- MOUSE_SHOW = 6,
- MOUSE_NO = 7,
- MOUSE_MOVE = 8, // +
- MOUSE_MOVEH = 9, // -
- MOUSE_MOVEV = 10, // |
- MOUSE_MOVED = 11, // /
- MOUSE_MOVEI = 12, // \ //
- MOUSE_SCROLLL = 13, // <<
- MOUSE_SCROLLR = 14, // >>
- MOUSE_SCROLLU = 15, // ^
- MOUSE_SCROLLD = 16, // v
- MOUSE_TARGET = 17
+ //! If true, draw mark
+ bool draw;
+ //! Phase of life
+ Gfx::EngineGroundMarkPhase phase;
+ //! Times for 3 life phases
+ float delay[3];
+ //! Fixed time
+ float fix;
+ //! Position for marks
+ Math::Vector pos;
+ //! Radius of marks
+ float radius;
+ //! Color intensity
+ float intensity;
+ //! Draw position for marks
+ Math::Vector drawPos;
+ //! Radius for marks
+ float drawRadius;
+ //! Draw intensity for marks
+ float drawIntensity;
+ //! X dimension of table
+ int dx;
+ //! Y dimension of table
+ int dy;
+ //! Pointer to the table
+ char* table;
+
+ EngineGroundMark()
+ {
+ draw = false;
+ delay[0] = delay[1] = delay[2] = 0.0f;
+ fix = radius = intensity = drawRadius = drawIntensity = 0.0f;
+ dx = dy = 0;
+ table = NULL;
+ }
};
-enum ShadowType
+/**
+ \enum EngineTextureMapping
+ \brief Type of texture mapping
+ */
+enum EngineTextureMapping
{
- SHADOW_NORM = 0,
- SHADOW_WORM = 1
+ ENG_TEX_MAPPING_X = 1,
+ ENG_TEX_MAPPING_Y = 2,
+ ENG_TEX_MAPPING_Z = 3,
+ ENG_TEX_MAPPING_1X = 4,
+ ENG_TEX_MAPPING_1Y = 5,
+ ENG_TEX_MAPPING_1Z = 6
};
+/**
+ \enum EngineRenderState
+ \brief Render state of graphics engine
+
+ States are used for settings certain modes, for instance texturing and blending.
+ The enum is a bitmask and some of the states can be OR'd together. */
enum EngineRenderState
{
//! Normal opaque materials
@@ -162,130 +408,70 @@ enum EngineRenderState
ENG_RSTATE_TCOLOR_WHITE = (1<<17)
};
-
-struct Triangle
-{
- Gfx::VertexTex2 triangle[3];
- Gfx::Material material;
- int state;
- char texName1[20];
- char texName2[20];
-};
-
-
-struct ObjLevel6
-{
- int totalPossible;
- int totalUsed;
- Gfx::Material material;
- int state;
- Gfx::TriangleType type;
- Gfx::VertexTex2 vertex[1];
-};
-
-struct ObjLevel5
-{
- int totalPossible;
- int totalUsed;
- int reserve;
- Gfx::ObjLevel6* table[1];
-};
-
-struct ObjLevel4
-{
- int totalPossible;
- int totalUsed;
- float min, max;
- Gfx::ObjLevel5* table[1];
-};
-
-struct ObjLevel3
-{
- int totalPossible;
- int totalUsed;
- int objRank;
- Gfx::ObjLevel4* table[1];
-};
-
-struct ObjLevel2
-{
- int totalPossible;
- int totalUsed;
- char texName1[20];
- char texName2[20];
- Gfx::ObjLevel3* table[1];
-};
-
-struct ObjLevel1
+/**
+ \enum EngineMouseType
+ \brief Type of mouse cursor displayed in-game */
+enum EngineMouseType
{
- int totalPossible;
- int totalUsed;
- Gfx::ObjLevel2* table[1];
+ //! Normal cursor (arrow)
+ ENG_MOUSE_NORM = 0,
+ //! Busy
+ ENG_MOUSE_WAIT = 1,
+ //! Edit (I-beam)
+ ENG_MOUSE_EDIT = 2,
+ //! Hand
+ ENG_MOUSE_HAND = 3,
+ //! Small cross
+ ENG_MOUSE_CROSS = 4,
+ //! TODO: ?
+ ENG_MOUSE_SHOW = 5,
+ //! Crossed out sign
+ ENG_MOUSE_NO = 6,
+ //! Resize
+ ENG_MOUSE_MOVE = 7,
+ //! Resize horizontally
+ ENG_MOUSE_MOVEH = 8,
+ //! Resize vertically
+ ENG_MOUSE_MOVEV = 9,
+ //! Resize diagonally bottom-left to top-right
+ ENG_MOUSE_MOVED = 10,
+ //! Resize diagonally top-left to bottom-right
+ ENG_MOUSE_MOVEI = 11,
+ //! Scroll to the left
+ ENG_MOUSE_SCROLLL = 12,
+ //! Scroll to the right
+ ENG_MOUSE_SCROLLR = 13,
+ //! Scroll up
+ ENG_MOUSE_SCROLLU = 14,
+ //! Scroll down
+ ENG_MOUSE_SCROLLD = 15,
+ //! Larger crosshair
+ ENG_MOUSE_TARGET = 16,
+
+ //! Number of items in enum
+ ENG_MOUSE_COUNT
};
+/**
+ \class CEngine
+ \brief The graphics engine
-struct Object
-{
- bool used; // true -> object exists
- bool visible; // true -> visible object
- bool drawWorld; // true -> shape behind the interface
- bool drawFront; // true -> shape before the interface
- int totalTriangle; // number of triangles used
- Gfx::ObjectType type; // type of the object (TYPE*)
- Math::Matrix transform; // transformation matrix
- float distance; // distance point of view - original
- Math::Vector bboxMin; // bounding box of the object
- Math::Vector bboxMax; // (the origin 0, 0, 0 is always included)
- float radius; // radius of the sphere at the origin
- int shadowRank; // rank of the associated shadow
- float transparency; // transparency of the object (0 .. 1)
-};
-
-struct Shadow
-{
- bool used; // true -> object exists
- bool hide; // true -> invisible shadow (object carried by ex.)
- int objRank; // rank of the object
- Gfx::ShadowType type; // type of shadow
- Math::Vector pos; // position for the shadow
- Math::Vector normal; // normal terrain
- float angle; // angle of the shadow
- float radius; // radius of the shadow
- float intensity; // intensity of the shadow
- float height; // height from the ground
-};
-
-struct GroundSpot
-{
- bool used; // true -> object exists
- Gfx::Color color; // color of the shadow
- float min, max; // altitudes min / max
- float smooth; // transition area
- Math::Vector pos; // position for the shadow
- float radius; // radius of the shadow
- Math::Vector drawPos; // drawn to position the shade
- float drawRadius; // radius of the shadow drawn
-};
+ This is the main class for graphics engine. It is responsible for drawing the 3D scene,
+ setting various render states, and facilitating the drawing of 2D interface.
-struct GroundMark
-{
- bool used; // true -> object exists
- bool draw; // true -> drawn mark
- int phase; // 1 = increase, 2 = fixed, 3 = decrease
- float delay[3]; // time for 3 phases
- float fix; // fixed time
- Math::Vector pos; // position for marks
- float radius; // radius of marks
- float intensity; // color intensity
- Math::Vector drawPos; // drawn in position marks
- float drawRadius; // radius marks drawn
- float drawIntensity; // current drawn
- int dx, dy; // dimensions table
- char* table; // pointer to the table
-};
+ It uses a lower-level CDevice object which is implementation-independent core engine.
+ \section Objecs Engine objects
+ The 3D scene is composed of objects which are basically collections of triangles forming
+ a surface or simply independent triangles in space. Objects are stored in the engine
+ as a tree structure which is composed of 5 tiers (EngineObjLevel1, EngineObjLevel2 and so on).
+ Each tier stores some data about object triangle, like textures or materials used.
+ Additional information on objects stored are in EngineObject structure.
+ Each object is uniquely identified by its rank.
+ ...
+ */
class CEngine
{
public:
@@ -304,12 +490,12 @@ public:
bool AfterDeviceSetInit();
+ void SetTerrain(Gfx::CTerrain* terrain);
- bool Render();
-
+ bool ProcessEvent(const Event &event);
+ bool Render();
- void SetTerrain(Gfx::CTerrain* terrain);
bool WriteProfile();
@@ -329,7 +515,7 @@ public:
int DeleteDeviceObjects();
int RestoreSurfaces();
int FrameMove(float rTime);
- void StepSimul(float rTime);
+ void StepSimulation(float rTime);
int FinalCleanup();
void AddStatisticTriangle(int nb);
int GetStatisticTriangle();
@@ -337,16 +523,10 @@ public:
bool GetHilite(Math::Point &p1, Math::Point &p2);
bool GetSpriteCoord(int &x, int &y);
void SetInfoText(int line, char* text);
- char * GetInfoText(int line);
- //LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ char* GetInfoText(int line);
void FirstExecuteAdapt(bool first);
- //int GetVidMemTotal();
- //bool IsVideo8MB();
- //bool IsVideo32MB();
- bool EnumDevices(char *bufDevices, int lenDevices, char *bufModes, int lenModes, int &totalDevices, int &selectDevices, int &totalModes, int &selectModes);
bool GetFullScreen();
- bool ChangeDevice(char *device, char *mode, bool full);
Math::Matrix* GetMatView();
Math::Matrix* GetMatLeftView();
@@ -363,27 +543,43 @@ public:
bool DeleteObject(int objRank);
bool SetDrawWorld(int objRank, bool draw);
bool SetDrawFront(int objRank, bool draw);
- bool AddTriangle(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material &mat, int state, char* texName1, char* texName2, float min, float max, bool globalUpdate);
- bool AddSurface(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material &mat, int state, char* texName1, char* texName2, float min, float max, bool globalUpdate);
- bool AddQuick(int objRank, Gfx::ObjLevel6* buffer, char* texName1, char* texName2, float min, float max, bool globalUpdate);
- Gfx::ObjLevel6* SearchTriangle(int objRank, const Gfx::Material &mat, int state, char* texName1, char* texName2, float min, float max);
+
+ bool AddTriangle(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material &mat,
+ int state, std::string texName1, std::string texName2,
+ float min, float max, bool globalUpdate);
+ bool AddSurface(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material &mat,
+ int state, std::string texName1, std::string texName2,
+ float min, float max, bool globalUpdate);
+ bool AddQuick(int objRank, Gfx::EngineObjLevel5* buffer,
+ std::string texName1, std::string texName2,
+ float min, float max, bool globalUpdate);
+ Gfx::EngineObjLevel5* SearchTriangle(int objRank, const Gfx::Material &mat,
+ int state, std::string texName1, std::string texName2,
+ float min, float max);
+
void ChangeLOD();
bool ChangeSecondTexture(int objRank, char* texName2);
int GetTotalTriangles(int objRank);
- int GetTriangles(int objRank, float min, float max, Gfx::Triangle* buffer, int size, float percent);
+ int GetTriangles(int objRank, float min, float max, Gfx::EngineTriangle* buffer, int size, float percent);
bool GetBBox(int objRank, Math::Vector &min, Math::Vector &max);
- bool ChangeTextureMapping(int objRank, const Gfx::Material &mat, int state, char* texName1, char* texName2, float min, float max, Gfx::Mapping mode, float au, float bu, float av, float bv);
- bool TrackTextureMapping(int objRank, const Gfx::Material &mat, int state, char* texName1, char* texName2, float min, float max, Gfx::Mapping mode, float pos, float factor, float tl, float ts, float tt);
+ bool ChangeTextureMapping(int objRank, const Gfx::Material &mat, int state,
+ const std::string &texName1, const std::string &texName2,
+ float min, float max, Gfx::EngineTextureMapping mode,
+ float au, float bu, float av, float bv);
+ bool TrackTextureMapping(int objRank, const Gfx::Material &mat, int state,
+ const std::string &texName1, const std::string &texName2,
+ float min, float max, Gfx::EngineTextureMapping mode,
+ float pos, float factor, float tl, float ts, float tt);
bool SetObjectTransform(int objRank, const Math::Matrix &transform);
bool GetObjectTransform(int objRank, Math::Matrix &transform);
- bool SetObjectType(int objRank, Gfx::ObjectType type);
- Gfx::ObjectType GetObjectType(int objRank);
+ bool SetObjectType(int objRank, Gfx::EngineObjectType type);
+ Gfx::EngineObjectType GetObjectType(int objRank);
bool SetObjectTransparency(int objRank, float value);
bool ShadowCreate(int objRank);
void ShadowDelete(int objRank);
bool SetObjectShadowHide(int objRank, bool hide);
- bool SetObjectShadowType(int objRank, Gfx::ShadowType type);
+ bool SetObjectShadowType(int objRank, Gfx::EngineShadowType type);
bool SetObjectShadowPos(int objRank, const Math::Vector &pos);
bool SetObjectShadowNormal(int objRank, const Math::Vector &n);
bool SetObjectShadowAngle(int objRank, float angle);
@@ -401,16 +597,23 @@ public:
bool SetObjectGroundSpotMinMax(int rank, float min, float max);
bool SetObjectGroundSpotSmooth(int rank, float smooth);
- int GroundMarkCreate(Math::Vector pos, float radius, float delay1, float delay2, float delay3, int dx, int dy, char* table);
+ int GroundMarkCreate(Math::Vector pos, float radius,
+ float delay1, float delay2, float delay3,
+ int dx, int dy, char* table);
bool GroundMarkDelete(int rank);
void Update();
- void SetViewParams(const Math::Vector &vEyePt, const Math::Vector &vLookatPt, const Math::Vector &vUpVec, float fEyeDistance);
+ void SetViewParams(const Math::Vector &eyePt, const Math::Vector &lookatPt,
+ const Math::Vector &upVec, float eyeDistance);
+
+ Gfx::Texture CreateTexture(const std::string &texName,
+ const Gfx::TextureCreateParams &params);
+ Gfx::Texture CreateTexture(const std::string &texName);
+ void DestroyTexture(const std::string &texName);
- bool FreeTexture(char* name);
- bool LoadTexture(char* name, int stage=0);
- bool LoadAllTexture();
+ bool LoadTexture(const std::string &name, int stage = 0);
+ bool LoadAllTextures();
void SetLimitLOD(int rank, float limit);
float GetLimitLOD(int rank, bool last=false);
@@ -436,30 +639,34 @@ public:
void SetDrawWorld(bool draw);
void SetDrawFront(bool draw);
- void SetAmbiantColor(const Gfx::Color &color, int rank=0);
- Gfx::Color GetAmbiantColor(int rank=0);
+ void SetAmbientColor(const Gfx::Color &color, int rank = 0);
+ Gfx::Color GetAmbientColor(int rank = 0);
void SetWaterAddColor(const Gfx::Color &color);
Gfx::Color GetWaterAddColor();
- void SetFogColor(const Gfx::Color &color, int rank=0);
- Gfx::Color GetFogColor(int rank=0);
+ void SetFogColor(const Gfx::Color &color, int rank = 0);
+ Gfx::Color GetFogColor(int rank = 0);
- void SetDeepView(float length, int rank=0, bool ref=false);
- float GetDeepView(int rank=0);
+ void SetDeepView(float length, int rank = 0, bool ref=false);
+ float GetDeepView(int rank = 0);
- void SetFogStart(float start, int rank=0);
- float GetFogStart(int rank=0);
+ void SetFogStart(float start, int rank = 0);
+ float GetFogStart(int rank = 0);
- void SetBackground(char *name, Gfx::Color up=Gfx::Color(), Gfx::Color down=Gfx::Color(), Gfx::Color cloudUp=Gfx::Color(), Gfx::Color cloudDown=Gfx::Color(), bool full=false, bool quarter=false);
- void GetBackground(char *name, Gfx::Color &up, Gfx::Color &down, Gfx::Color &cloudUp, Gfx::Color &cloudDown, bool &full, bool &quarter);
+ void SetBackground(const std::string &name, Gfx::Color up = Gfx::Color(), Gfx::Color down = Gfx::Color(),
+ Gfx::Color cloudUp = Gfx::Color(), Gfx::Color cloudDown = Gfx::Color(),
+ bool full = false, bool quarter = false);
+ void GetBackground(const std::string &name, Gfx::Color &up, Gfx::Color &down,
+ Gfx::Color &cloudUp, Gfx::Color &cloudDown,
+ bool &full, bool &quarter);
void SetFrontsizeName(char *name);
void SetOverFront(bool front);
- void SetOverColor(const Gfx::Color &color=Gfx::Color(), int mode=ENG_RSTATE_TCOLOR_BLACK);
+ void SetOverColor(const Gfx::Color &color = Gfx::Color(), int mode = ENG_RSTATE_TCOLOR_BLACK);
- void SetParticuleDensity(float value);
- float GetParticuleDensity();
- float ParticuleAdapt(float factor);
+ void SetParticleDensity(float value);
+ float GetParticleDensity();
+ float ParticleAdapt(float factor);
void SetClippingDistance(float value);
float GetClippingDistance();
@@ -482,8 +689,8 @@ public:
void SetWaterMode(bool present);
bool GetWaterMode();
- void SetBlitzMode(bool present);
- bool GetBlitzMode();
+ void SetLightingMode(bool present);
+ bool GetLightingMode();
void SetSkyMode(bool present);
bool GetSkyMode();
@@ -535,24 +742,24 @@ public:
bool IsVisiblePoint(const Math::Vector &pos);
int DetectObject(Math::Point mouse);
- void SetState(int state, Gfx::Color color=Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f));
- void SetTexture(char *name, int stage=0);
+ void SetState(int state, Gfx::Color color = Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f));
+ void SetTexture(const std::string &name, int stage = 0);
void SetMaterial(const Gfx::Material &mat);
- void MoveMousePos(Math::Point pos);
- void SetMousePos(Math::Point pos);
- Math::Point GetMousePos();
- void SetMouseType(Gfx::MouseType type);
- Gfx::MouseType GetMouseType();
- void SetMouseHide(bool hide);
- bool GetMouseHide();
- void SetNiceMouse(bool nice);
- bool GetNiceMouse();
- bool GetNiceMouseCap();
+ void SetMouseVisible(bool show);
+ bool GetMouseVisible();
+ void SetMousePos(Math::Point pos);
+ Math::Point GetMousePos();
+ void SetMouseType(Gfx::EngineMouseType type);
+ Gfx::EngineMouseType GetMouseType();
CText* GetText();
- bool ChangeColor(char *name, Gfx::Color colorRef1, Gfx::Color colorNew1, Gfx::Color colorRef2, Gfx::Color colorNew2, float tolerance1, float tolerance2, Math::Point ts, Math::Point ti, Math::Point *pExclu=0, float shift=0.0f, bool hSV=false);
+ bool ChangeColor(char *name, Gfx::Color colorRef1, Gfx::Color colorNew1,
+ Gfx::Color colorRef2, Gfx::Color colorNew2,
+ float tolerance1, float tolerance2,
+ Math::Point ts, Math::Point ti,
+ Math::Point *pExclu=0, float shift=0.0f, bool hSV=false);
bool OpenImage(char *name);
bool CopyImage();
bool LoadImage();
@@ -566,26 +773,14 @@ public:
//bool CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC);
protected:
- void MemSpace1(Gfx::ObjLevel1 *&p, int nb);
- void MemSpace2(Gfx::ObjLevel2 *&p, int nb);
- void MemSpace3(Gfx::ObjLevel3 *&p, int nb);
- void MemSpace4(Gfx::ObjLevel4 *&p, int nb);
- void MemSpace5(Gfx::ObjLevel5 *&p, int nb);
- void MemSpace6(Gfx::ObjLevel6 *&p, int nb);
- Gfx::ObjLevel2* AddLevel1(Gfx::ObjLevel1 *&p1, char* texName1, char* texName2);
- Gfx::ObjLevel3* AddLevel2(Gfx::ObjLevel2 *&p2, int objRank);
- Gfx::ObjLevel4* AddLevel3(Gfx::ObjLevel3 *&p3, float min, float max);
- Gfx::ObjLevel5* AddLevel4(Gfx::ObjLevel4 *&p4, int reserve);
- Gfx::ObjLevel6* AddLevel5(Gfx::ObjLevel5 *&p5, Gfx::TriangleType type, const Gfx::Material &mat, int state, int nb);
+ void SetUp3DView();
+ bool Draw3DScene();
- bool IsVisible(int objRank);
- bool DetectBBox(int objRank, Math::Point mouse);
- bool DetectTriangle(Math::Point mouse, Gfx::VertexTex2 *triangle, int objRank, float &dist);
- bool TransformPoint(Math::Vector &p2D, int objRank, Math::Vector p3D);
- void ComputeDistance();
- void UpdateGeometry();
- void RenderGroundSpot();
+ void SetUpInterfaceView();
+ bool DrawInterface();
+
+ void DrawGroundSpot();
void DrawShadow();
void DrawBackground();
void DrawBackgroundGradient(Gfx::Color up, Gfx::Color down);
@@ -594,14 +789,29 @@ protected:
void DrawPlanet();
void DrawFrontsize();
void DrawOverColor();
- bool GetBBox2D(int objRank, Math::Point &min, Math::Point &max);
void DrawHilite();
void DrawMouse();
- void DrawSprite(Math::Point pos, Math::Point dim, int icon);
+ void DrawMouseSprite(Math::Point pos, Math::Point dim, int icon);
+
+ /*
+ Gfx::ObjLevel2* AddLevel1(Gfx::ObjLevel1 *&p1, char* texName1, char* texName2);
+ Gfx::ObjLevel3* AddLevel2(Gfx::ObjLevel2 *&p2, int objRank);
+ Gfx::ObjLevel4* AddLevel3(Gfx::ObjLevel3 *&p3, float min, float max);
+ Gfx::ObjLevel5* AddLevel4(Gfx::ObjLevel4 *&p4, int reserve);
+ Gfx::ObjLevel6* AddLevel5(Gfx::ObjLevel5 *&p5, Gfx::TriangleType type, const Gfx::Material &mat, int state, int nb);*/
+
+ bool IsVisible(int objRank);
+ bool DetectBBox(int objRank, Math::Point mouse);
+ bool GetBBox2D(int objRank, Math::Point &min, Math::Point &max);
+ bool DetectTriangle(Math::Point mouse, Gfx::VertexTex2 *triangle, int objRank, float &dist);
+ bool TransformPoint(Math::Vector &p2D, int objRank, Math::Vector p3D);
+ void ComputeDistance();
+ void UpdateGeometry();
protected:
CInstanceManager* m_iMan;
CApplication* m_app;
+ CSound* m_sound;
Gfx::CDevice* m_device;
Gfx::CText* m_text;
Gfx::CLight* m_light;
@@ -611,7 +821,6 @@ protected:
Gfx::CLightning* m_lightning;
Gfx::CPlanet* m_planet;
Gfx::CTerrain* m_terrain;
- CSound* m_sound;
bool m_wasInit;
std::string m_error;
@@ -644,21 +853,21 @@ protected:
bool m_render;
bool m_movieLock;
- Math::IntPoint m_dim;
- Math::IntPoint m_lastDim;
- Gfx::ObjLevel1* m_objectPointer;
- int m_objectParamTotal;
- Gfx::Object* m_objectParam;
- int m_shadowTotal;
- Gfx::Shadow* m_shadow;
- Gfx::GroundSpot* m_groundSpot;
- Gfx::GroundMark m_groundMark;
- Math::Vector m_eyePt;
- Math::Vector m_lookatPt;
+ Math::IntPoint m_dim;
+ Math::IntPoint m_lastDim;
+
+ std::vector<Gfx::EngineObjLevel1> m_objectTree;
+ std::vector<Gfx::EngineObject> m_objects;
+ std::vector<Gfx::EngineShadow> m_shadow;
+ std::vector<Gfx::EngineGroundSpot> m_groundSpot;
+ Gfx::EngineGroundMark m_groundMark;
+
+ Math::Vector m_eyePt;
+ Math::Vector m_lookatPt;
float m_eyeDirH;
float m_eyeDirV;
int m_rankView;
- Gfx::Color m_ambiantColor[2];
+ Gfx::Color m_ambientColor[2];
Gfx::Color m_backColor[2];
Gfx::Color m_fogColor[2];
float m_deepView[2];
@@ -666,7 +875,7 @@ protected:
Gfx::Color m_waterAddColor;
int m_statisticTriangle;
bool m_updateGeometry;
- char m_infoText[10][200];
+ //char m_infoText[10][200];
int m_alphaMode;
bool m_stateColor;
bool m_forceStateColor;
@@ -676,7 +885,7 @@ protected:
bool m_fog;
bool m_firstGroundSpot;
int m_secondTexNum;
- char m_backgroundName[50];
+ std::string m_backgroundName;
Gfx::Color m_backgroundColorUp;
Gfx::Color m_backgroundColorDown;
Gfx::Color m_backgroundCloudUp;
@@ -686,7 +895,7 @@ protected:
bool m_overFront;
Gfx::Color m_overColor;
int m_overMode;
- char m_frontsizeName[50];
+ std::string m_frontsizeName;
bool m_drawWorld;
bool m_drawFront;
float m_limitLOD[2];
@@ -719,10 +928,15 @@ protected:
char m_lastTexture[2][50];
Gfx::Material m_lastMaterial;
- Math::Point m_mousePos;
- Gfx::MouseType m_mouseType;
- bool m_mouseHide;
- bool m_niceMouse;
+ std::string m_texPath;
+ Gfx::TextureCreateParams m_defaultTexParams;
+
+ std::map<std::string, Gfx::Texture> m_texNameMap;
+ std::map<Gfx::Texture, std::string> m_revTexNameMap;
+
+ Gfx::EngineMouseType m_mouseType;
+ Math::Point m_mousePos;
+ bool m_mouseVisible;
//LPDIRECTDRAWSURFACE7 m_imageSurface;
//DDSURFACEDESC2 m_imageDDSD;
diff --git a/src/graphics/common/light.h b/src/graphics/common/light.h
index f85d8da..46f1bfa 100644
--- a/src/graphics/common/light.h
+++ b/src/graphics/common/light.h
@@ -114,9 +114,9 @@ struct SceneLight
bool enabled;
//! Type of all objects included
- Gfx::ObjectType includeType;
+ Gfx::EngineObjectType includeType;
//! Type of all objects excluded
- Gfx::ObjectType excludeType;
+ Gfx::EngineObjectType excludeType;
//! Configuration of the light
Gfx::Light light;
diff --git a/src/graphics/common/particle.h b/src/graphics/common/particle.h
index ec87648..bd9741f 100644
--- a/src/graphics/common/particle.h
+++ b/src/graphics/common/particle.h
@@ -265,7 +265,7 @@ public:
void FlushParticle();
void FlushParticle(int sheet);
int CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point dim, ParticleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0);
- int CreateFrag(Math::Vector pos, Math::Vector speed, Triangle *triangle, ParticleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0);
+ int CreateFrag(Math::Vector pos, Math::Vector speed, Gfx::EngineTriangle *triangle, ParticleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0);
int CreatePart(Math::Vector pos, Math::Vector speed, ParticleType type, float duration=1.0f, float mass=0.0f, float weight=0.0f, float windSensitivity=1.0f, int sheet=0);
int CreateRay(Math::Vector pos, Math::Vector goal, ParticleType type, Math::Point dim, float duration=1.0f, int sheet=0);
int CreateTrack(Math::Vector pos, Math::Vector speed, Math::Point dim, ParticleType type, float duration=1.0f, float mass=0.0f, float length=10.0f, float width=1.0f);
@@ -318,7 +318,7 @@ protected:
CSound* m_sound;
Gfx::Particle m_particule[MAXPARTICULE*MAXPARTITYPE];
- Gfx::Triangle m_triangle[MAXPARTICULE]; // triangle if PartiType == 0
+ Gfx::EngineTriangle m_triangle[MAXPARTICULE]; // triangle if PartiType == 0
Track m_track[MAXTRACK];
int m_wheelTraceTotal;
int m_wheelTraceIndex;
diff --git a/src/graphics/common/texture.h b/src/graphics/common/texture.h
index fa374ac..83986ea 100644
--- a/src/graphics/common/texture.h
+++ b/src/graphics/common/texture.h
@@ -166,9 +166,48 @@ struct Texture
bool valid;
//! Id of the texture in graphics engine
unsigned int id;
+ //! Width of texture
+ int width;
+ //! Height of texture
+ int height;
+ //! Whether the texture has alpha channel
+ bool alpha;
Texture()
- { valid = false; id = 0; }
+ {
+ valid = false;
+ id = 0;
+ width = height = 0;
+ alpha = false;
+ }
+
+ //! Comparator for use in texture maps and sets
+ inline bool operator<(const Gfx::Texture &other) const
+ {
+ // Invalid textures are always "less than" every other texture
+
+ if ( (!valid) && (!other.valid) )
+ return false;
+
+ if (!valid)
+ return true;
+
+ if (!other.valid)
+ return false;
+
+ return id < other.id;
+ }
+
+ //! Comparator
+ inline bool operator==(const Gfx::Texture &other) const
+ {
+ if (valid != other.valid)
+ return false;
+ if ( (!valid) && (!other.valid) )
+ return true;
+
+ return id == other.id;
+ }
};
}; // namespace Gfx
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index 19a9cff..3d63bf2 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -30,21 +30,6 @@
#include <assert.h>
-namespace Gfx {
-
-struct GLDevicePrivate
-{
- void (APIENTRY* glMultiTexCoord2fARB)(GLenum target, GLfloat s, GLfloat t);
- void (APIENTRY* glActiveTextureARB)(GLenum texture);
-
- GLDevicePrivate()
- {
- glMultiTexCoord2fARB = NULL;
- glActiveTextureARB = NULL;
- }
-};
-
-}; // namespace Gfx
void Gfx::GLDeviceConfig::LoadDefault()
@@ -65,7 +50,6 @@ void Gfx::GLDeviceConfig::LoadDefault()
Gfx::CGLDevice::CGLDevice()
{
- m_private = new Gfx::GLDevicePrivate();
m_wasInit = false;
m_texturing = false;
}
@@ -73,8 +57,6 @@ Gfx::CGLDevice::CGLDevice()
Gfx::CGLDevice::~CGLDevice()
{
- delete m_private;
- m_private = NULL;
}
bool Gfx::CGLDevice::GetWasInit()
@@ -108,15 +90,6 @@ bool Gfx::CGLDevice::Create()
return false;
}
- /*m_private->glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord2fARB");
- m_private->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB");
-
- if ((m_private->glMultiTexCoord2fARB == NULL) || (m_private->glActiveTextureARB == NULL))
- {
- m_error = "Could not load extension functions, even though they seem supported";
- return false;
- }*/
-
m_wasInit = true;
// This is mostly done in all modern hardware by default
@@ -141,7 +114,7 @@ bool Gfx::CGLDevice::Create()
int maxTextures = 0;
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextures);
- m_textures = std::vector<Gfx::Texture*> (maxTextures, (Gfx::Texture*)(NULL));
+ m_textures = std::vector<Gfx::Texture> (maxTextures, Gfx::Texture());
m_texturesEnabled = std::vector<bool> (maxTextures, false);
m_texturesParams = std::vector<Gfx::TextureParams>(maxTextures, Gfx::TextureParams());
@@ -150,9 +123,6 @@ bool Gfx::CGLDevice::Create()
void Gfx::CGLDevice::Destroy()
{
- /*m_private->glMultiTexCoord2fARB = NULL;
- m_private->glActiveTextureARB = NULL;*/
-
// Delete the remaining textures
// Should not be strictly necessary, but just in case
DestroyAllTextures();
@@ -174,8 +144,7 @@ void Gfx::CGLDevice::BeginScene()
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(m_projectionMat.Array());
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(m_modelviewMat.Array());
+ UpdateModelviewMatrix();
}
void Gfx::CGLDevice::EndScene()
@@ -193,16 +162,12 @@ void Gfx::CGLDevice::SetTransform(Gfx::TransformType type, const Math::Matrix &m
if (type == Gfx::TRANSFORM_WORLD)
{
m_worldMat = matrix;
- m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(m_modelviewMat.Array());
+ UpdateModelviewMatrix();
}
else if (type == Gfx::TRANSFORM_VIEW)
{
m_viewMat = matrix;
- m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(m_modelviewMat.Array());
+ UpdateModelviewMatrix();
}
else if (type == Gfx::TRANSFORM_PROJECTION)
{
@@ -235,16 +200,12 @@ void Gfx::CGLDevice::MultiplyTransform(Gfx::TransformType type, const Math::Matr
if (type == Gfx::TRANSFORM_WORLD)
{
m_worldMat = Math::MultiplyMatrices(m_worldMat, matrix);
- m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(m_modelviewMat.Array());
+ UpdateModelviewMatrix();
}
else if (type == Gfx::TRANSFORM_VIEW)
{
m_viewMat = Math::MultiplyMatrices(m_viewMat, matrix);
- m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(m_modelviewMat.Array());
+ UpdateModelviewMatrix();
}
else if (type == Gfx::TRANSFORM_PROJECTION)
{
@@ -258,7 +219,17 @@ void Gfx::CGLDevice::MultiplyTransform(Gfx::TransformType type, const Math::Matr
}
}
-void Gfx::CGLDevice::SetMaterial(Gfx::Material &material)
+void Gfx::CGLDevice::UpdateModelviewMatrix()
+{
+ m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glScalef(1.0f, 1.0f, -1.0f);
+ glMultMatrixf(m_modelviewMat.Array());
+}
+
+void Gfx::CGLDevice::SetMaterial(const Gfx::Material &material)
{
m_material = material;
@@ -277,7 +248,7 @@ int Gfx::CGLDevice::GetMaxLightCount()
return m_lights.size();
}
-void Gfx::CGLDevice::SetLight(int index, Gfx::Light &light)
+void Gfx::CGLDevice::SetLight(int index, const Gfx::Light &light)
{
assert(index >= 0);
assert(index < (int)m_lights.size());
@@ -285,9 +256,9 @@ void Gfx::CGLDevice::SetLight(int index, Gfx::Light &light)
m_lights[index] = light;
// Indexing from GL_LIGHT0 should always work
- glLightfv(GL_LIGHT0 + index, GL_AMBIENT, light.ambient.Array());
- glLightfv(GL_LIGHT0 + index, GL_DIFFUSE, light.diffuse.Array());
- glLightfv(GL_LIGHT0 + index, GL_SPECULAR, light.specular.Array());
+ glLightfv(GL_LIGHT0 + index, GL_AMBIENT, const_cast<GLfloat*>(light.ambient.Array()));
+ glLightfv(GL_LIGHT0 + index, GL_DIFFUSE, const_cast<GLfloat*>(light.diffuse.Array()));
+ glLightfv(GL_LIGHT0 + index, GL_SPECULAR, const_cast<GLfloat*>(light.specular.Array()));
GLfloat position[4] = { light.position.x, light.position.y, light.position.z, 0.0f };
if (light.type == LIGHT_DIRECTIONAL)
@@ -334,17 +305,23 @@ bool Gfx::CGLDevice::GetLightEnabled(int index)
return m_lightsEnabled[index];
}
-/** If image is invalid, returns NULL.
+/** If image is invalid, returns invalid texture.
Otherwise, returns pointer to new Gfx::Texture struct.
This struct must not be deleted in other way than through DeleteTexture() */
-Gfx::Texture* Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCreateParams &params)
+Gfx::Texture Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCreateParams &params)
{
+ Gfx::Texture result;
+
ImageData *data = image->GetData();
if (data == NULL)
- return NULL;
+ {
+ m_error = "Invalid texture data";
+ return result; // invalid texture
+ }
- Gfx::Texture *result = new Gfx::Texture();
- result->valid = true;
+ result.valid = true;
+ result.width = data->surface->w;
+ result.height = data->surface->h;
// Use & enable 1st texture stage
glActiveTextureARB(GL_TEXTURE0_ARB);
@@ -352,8 +329,8 @@ Gfx::Texture* Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCre
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glGenTextures(1, &result->id);
- glBindTexture(GL_TEXTURE_2D, result->id);
+ glGenTextures(1, &result.id);
+ glBindTexture(GL_TEXTURE_2D, result.id);
// Set params
@@ -395,13 +372,25 @@ Gfx::Texture* Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCre
GLenum sourceFormat = 0;
if (params.format == Gfx::TEX_IMG_RGB)
+ {
sourceFormat = GL_RGB;
+ result.alpha = false;
+ }
else if (params.format == Gfx::TEX_IMG_BGR)
+ {
sourceFormat = GL_BGR;
+ result.alpha = false;
+ }
else if (params.format == Gfx::TEX_IMG_RGBA)
+ {
sourceFormat = GL_RGBA;
+ result.alpha = true;
+ }
else if (params.format == Gfx::TEX_IMG_BGRA)
+ {
sourceFormat = GL_BGRA;
+ result.alpha = true;
+ }
else
assert(false);
@@ -410,10 +399,10 @@ Gfx::Texture* Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCre
// Restore the previous state of 1st stage
- if (m_textures[0] == NULL)
- glBindTexture(GL_TEXTURE_2D, 0);
+ if (m_textures[0].valid)
+ glBindTexture(GL_TEXTURE_2D, m_textures[0].id);
else
- glBindTexture(GL_TEXTURE_2D, m_textures[0]->id);
+ glBindTexture(GL_TEXTURE_2D, 0);
if ( (! m_texturing) || (! m_texturesEnabled[0]) )
glDisable(GL_TEXTURE_2D);
@@ -421,9 +410,9 @@ Gfx::Texture* Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCre
return result;
}
-void Gfx::CGLDevice::DestroyTexture(Gfx::Texture *texture)
+void Gfx::CGLDevice::DestroyTexture(const Gfx::Texture &texture)
{
- std::set<Gfx::Texture*>::iterator it = m_allTextures.find(texture);
+ std::set<Gfx::Texture>::iterator it = m_allTextures.find(texture);
if (it != m_allTextures.end())
m_allTextures.erase(it);
@@ -431,21 +420,18 @@ void Gfx::CGLDevice::DestroyTexture(Gfx::Texture *texture)
for (int index = 0; index < (int)m_textures.size(); ++index)
{
if (m_textures[index] == texture)
- SetTexture(index, NULL);
+ SetTexture(index, Gfx::Texture()); // set to invalid texture
}
- glDeleteTextures(1, &texture->id);
+ glDeleteTextures(1, &texture.id);
}
void Gfx::CGLDevice::DestroyAllTextures()
{
- std::set<Gfx::Texture*> allCopy = m_allTextures;
- std::set<Gfx::Texture*>::iterator it;
+ std::set<Gfx::Texture> allCopy = m_allTextures;
+ std::set<Gfx::Texture>::iterator it;
for (it = allCopy.begin(); it != allCopy.end(); ++it)
- {
DestroyTexture(*it);
- delete *it;
- }
}
int Gfx::CGLDevice::GetMaxTextureCount()
@@ -454,10 +440,10 @@ int Gfx::CGLDevice::GetMaxTextureCount()
}
/**
- If \a texture is \c NULL or invalid, unbinds the given texture.
+ If \a texture is invalid, unbinds the given texture.
If valid, binds the texture and enables the given texture stage.
The setting is remembered, even if texturing is disabled at the moment. */
-void Gfx::CGLDevice::SetTexture(int index, Gfx::Texture *texture)
+void Gfx::CGLDevice::SetTexture(int index, const Gfx::Texture &texture)
{
assert(index >= 0);
assert(index < (int)m_textures.size());
@@ -466,15 +452,15 @@ void Gfx::CGLDevice::SetTexture(int index, Gfx::Texture *texture)
glActiveTextureARB(GL_TEXTURE0_ARB + index);
glEnable(GL_TEXTURE_2D);
- if ((texture == NULL) || (! texture->valid))
+ m_textures[index] = texture; // remember the change
+
+ if (! texture.valid)
{
glBindTexture(GL_TEXTURE_2D, 0); // unbind texture
- m_textures[index] = NULL; // remember the changes
}
else
{
- glBindTexture(GL_TEXTURE_2D, texture->id); // bind the texture
- m_textures[index] = texture; // remember the changes
+ glBindTexture(GL_TEXTURE_2D, texture.id); // bind the texture
SetTextureParams(index, m_texturesParams[index]); // texture params need to be re-set for the new texture
}
@@ -484,8 +470,8 @@ void Gfx::CGLDevice::SetTexture(int index, Gfx::Texture *texture)
}
/**
- Returns the previously assigned texture or \c NULL if the given stage is not enabled. */
-Gfx::Texture* Gfx::CGLDevice::GetTexture(int index)
+ Returns the previously assigned texture or invalid texture if the given stage is not enabled. */
+Gfx::Texture Gfx::CGLDevice::GetTexture(int index)
{
assert(index >= 0);
assert(index < (int)m_textures.size());
@@ -528,14 +514,14 @@ void Gfx::CGLDevice::SetTextureParams(int index, const Gfx::TextureParams &param
m_texturesParams[index] = params;
// Don't actually do anything if texture not set
- if (m_textures[index] == NULL)
+ if (! m_textures[index].valid)
return;
// Enable the given stage
glActiveTextureARB(GL_TEXTURE0_ARB + index);
glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, m_textures[index]->id);
+ glBindTexture(GL_TEXTURE_2D, m_textures[index].id);
// Selection of operation and arguments
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@@ -639,7 +625,7 @@ Gfx::TextureParams Gfx::CGLDevice::GetTextureParams(int index)
return m_texturesParams[index];
}
-void Gfx::CGLDevice::SetTextureFactor(Gfx::Color &color)
+void Gfx::CGLDevice::SetTextureFactor(const Gfx::Color &color)
{
// Needs to be set for all texture stages
for (int index = 0; index < (int)m_textures.size(); ++index)
@@ -749,7 +735,7 @@ bool InPlane(Math::Vector normal, float originPlane, Math::Vector center, float
*/
// TODO: testing
-int Gfx::CGLDevice::ComputeSphereVisibility(Math::Vector center, float radius)
+int Gfx::CGLDevice::ComputeSphereVisibility(const Math::Vector &center, float radius)
{
Math::Matrix m;
m.LoadIdentity();
@@ -847,6 +833,7 @@ void Gfx::CGLDevice::SetRenderState(Gfx::RenderState state, bool enabled)
case Gfx::RENDER_STATE_FOG: flag = GL_FOG; break;
case Gfx::RENDER_STATE_DEPTH_TEST: flag = GL_DEPTH_TEST; break;
case Gfx::RENDER_STATE_ALPHA_TEST: flag = GL_ALPHA_TEST; break;
+ case Gfx::RENDER_STATE_CULLING: flag = GL_CULL_FACE; break;
case Gfx::RENDER_STATE_DITHERING: flag = GL_DITHER; break;
default: assert(false); break;
}
@@ -872,6 +859,7 @@ bool Gfx::CGLDevice::GetRenderState(Gfx::RenderState state)
case Gfx::RENDER_STATE_FOG: flag = GL_FOG; break;
case Gfx::RENDER_STATE_DEPTH_TEST: flag = GL_DEPTH_TEST; break;
case Gfx::RENDER_STATE_ALPHA_TEST: flag = GL_ALPHA_TEST; break;
+ case Gfx::RENDER_STATE_CULLING: flag = GL_CULL_FACE; break;
case Gfx::RENDER_STATE_DITHERING: flag = GL_DITHER; break;
default: assert(false); break;
}
@@ -1011,7 +999,7 @@ void Gfx::CGLDevice::GetBlendFunc(Gfx::BlendFunc &srcBlend, Gfx::BlendFunc &dstB
dstBlend = TranslateGLBlendFunc(dstFlag);
}
-void Gfx::CGLDevice::SetClearColor(Gfx::Color color)
+void Gfx::CGLDevice::SetClearColor(const Gfx::Color &color)
{
glClearColor(color.r, color.g, color.b, color.a);
}
@@ -1023,7 +1011,7 @@ Gfx::Color Gfx::CGLDevice::GetClearColor()
return Gfx::Color(color[0], color[1], color[2], color[3]);
}
-void Gfx::CGLDevice::SetGlobalAmbient(Gfx::Color color)
+void Gfx::CGLDevice::SetGlobalAmbient(const Gfx::Color &color)
{
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, color.Array());
}
@@ -1035,7 +1023,7 @@ Gfx::Color Gfx::CGLDevice::GetGlobalAmbient()
return Gfx::Color(color[0], color[1], color[2], color[3]);
}
-void Gfx::CGLDevice::SetFogParams(Gfx::FogMode mode, Gfx::Color color, float start, float end, float density)
+void Gfx::CGLDevice::SetFogParams(Gfx::FogMode mode, const Gfx::Color &color, float start, float end, float density)
{
if (mode == Gfx::FOG_LINEAR) glFogi(GL_FOG_MODE, GL_LINEAR);
else if (mode == Gfx::FOG_EXP) glFogi(GL_FOG_MODE, GL_EXP);
diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h
index 56ea2c0..792ea4b 100644
--- a/src/graphics/opengl/gldevice.h
+++ b/src/graphics/opengl/gldevice.h
@@ -88,36 +88,36 @@ public:
virtual const Math::Matrix& GetTransform(Gfx::TransformType type);
virtual void MultiplyTransform(Gfx::TransformType type, const Math::Matrix &matrix);
- virtual void SetMaterial(Gfx::Material &material);
+ virtual void SetMaterial(const Gfx::Material &material);
virtual const Gfx::Material& GetMaterial();
virtual int GetMaxLightCount();
- virtual void SetLight(int index, Gfx::Light &light);
+ virtual void SetLight(int index, const Gfx::Light &light);
virtual const Gfx::Light& GetLight(int index);
virtual void SetLightEnabled(int index, bool enabled);
virtual bool GetLightEnabled(int index);
- virtual Gfx::Texture* CreateTexture(CImage *image, const Gfx::TextureCreateParams &params);
- virtual void DestroyTexture(Gfx::Texture *texture);
+ virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams &params);
+ virtual void DestroyTexture(const Gfx::Texture &texture);
virtual void DestroyAllTextures();
virtual int GetMaxTextureCount();
- virtual void SetTexture(int index, Gfx::Texture *texture);
- virtual Gfx::Texture* GetTexture(int index);
+ virtual void SetTexture(int index, const Gfx::Texture &texture);
+ virtual Gfx::Texture GetTexture(int index);
virtual void SetTextureEnabled(int index, bool enabled);
virtual bool GetTextureEnabled(int index);
virtual void SetTextureParams(int index, const Gfx::TextureParams &params);
virtual Gfx::TextureParams GetTextureParams(int index);
- virtual void SetTextureFactor(Gfx::Color &color);
+ virtual void SetTextureFactor(const Gfx::Color &color);
virtual Gfx::Color GetTextureFactor();
virtual void DrawPrimitive(Gfx::PrimitiveType type, Vertex *vertices, int vertexCount);
virtual void DrawPrimitive(Gfx::PrimitiveType type, Gfx::VertexCol *vertices, int vertexCount);
virtual void DrawPrimitive(Gfx::PrimitiveType type, VertexTex2 *vertices, int vertexCount);
- virtual int ComputeSphereVisibility(Math::Vector center, float radius);
+ virtual int ComputeSphereVisibility(const Math::Vector &center, float radius);
virtual void SetRenderState(Gfx::RenderState state, bool enabled);
virtual bool GetRenderState(Gfx::RenderState state);
@@ -134,13 +134,13 @@ public:
virtual void SetBlendFunc(Gfx::BlendFunc srcBlend, Gfx::BlendFunc dstBlend);
virtual void GetBlendFunc(Gfx::BlendFunc &srcBlend, Gfx::BlendFunc &dstBlend);
- virtual void SetClearColor(Gfx::Color color);
+ virtual void SetClearColor(const Gfx::Color &color);
virtual Gfx::Color GetClearColor();
- virtual void SetGlobalAmbient(Gfx::Color color);
+ virtual void SetGlobalAmbient(const Gfx::Color &color);
virtual Gfx::Color GetGlobalAmbient();
- virtual void SetFogParams(Gfx::FogMode mode, Gfx::Color color, float start, float end, float density);
+ virtual void SetFogParams(Gfx::FogMode mode, const Gfx::Color &color, float start, float end, float density);
virtual void GetFogParams(Gfx::FogMode &mode, Gfx::Color &color, float &start, float &end, float &density);
virtual void SetCullMode(Gfx::CullMode mode);
@@ -153,8 +153,9 @@ public:
virtual Gfx::FillMode GetFillMode();
private:
- //! Private, OpenGL-specific data
- GLDevicePrivate* m_private;
+ void UpdateModelviewMatrix();
+
+private:
//! Was initialized?
bool m_wasInit;
//! Last encountered error
@@ -180,14 +181,14 @@ private:
//! Whether texturing is enabled in general
bool m_texturing;
//! Current textures; \c NULL value means unassigned
- std::vector<Gfx::Texture*> m_textures;
+ std::vector<Gfx::Texture> m_textures;
//! Current texture stages enable status
std::vector<bool> m_texturesEnabled;
//! Current texture params
std::vector<Gfx::TextureParams> m_texturesParams;
//! Set of all created textures
- std::set<Gfx::Texture*> m_allTextures;
+ std::set<Gfx::Texture> m_allTextures;
};
}; // namespace Gfx
diff --git a/src/graphics/opengl/glengine.cpp b/src/graphics/opengl/glengine.cpp
deleted file mode 100644
index 9aab348..0000000
--- a/src/graphics/opengl/glengine.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// * This file is part of the COLOBOT source code
-// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// glengine.h
-
-#include "graphics/opengl/glengine.h"
-
-// TODO \ No newline at end of file
diff --git a/src/graphics/opengl/glengine.h b/src/graphics/opengl/glengine.h
deleted file mode 100644
index fa67bfe..0000000
--- a/src/graphics/opengl/glengine.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// * This file is part of the COLOBOT source code
-// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// glengine.h
-
-#pragma once
-
-
-#include "graphics/common/engine.h"
-
-namespace Gfx
-{
-
-class CGLEngine : public Gfx::CEngine
-{
- // TODO
-};
-
-};
diff --git a/src/graphics/opengl/test/model_test.cpp b/src/graphics/opengl/test/model_test.cpp
index 88404b7..3aad1b6 100644
--- a/src/graphics/opengl/test/model_test.cpp
+++ b/src/graphics/opengl/test/model_test.cpp
@@ -34,15 +34,15 @@ Math::Vector ROTATION;
const int FRAME_DELAY = 5000;
-std::map<std::string, Gfx::Texture*> TEXS;
+std::map<std::string, Gfx::Texture> TEXS;
SystemTimeStamp *PREV_TIME = NULL, *CURR_TIME = NULL;
-Gfx::Texture* GetTexture(const std::string &name)
+Gfx::Texture GetTexture(const std::string &name)
{
- std::map<std::string, Gfx::Texture*>::iterator it = TEXS.find(name);
+ std::map<std::string, Gfx::Texture>::iterator it = TEXS.find(name);
if (it == TEXS.end())
- return NULL;
+ return Gfx::Texture();
return (*it).second;
}
@@ -52,10 +52,10 @@ void LoadTexture(Gfx::CGLDevice *device, const std::string &name)
if (name.empty())
return;
- if (GetTexture(name) != NULL)
- return;
+ Gfx::Texture tex = GetTexture(name);
- Gfx::Texture *tex = NULL;
+ if (tex.valid)
+ return;
CImage img;
if (! img.Load(std::string("tex/") + name))
@@ -114,7 +114,7 @@ void Render(Gfx::CGLDevice *device, Gfx::CModelFile *modelFile)
device->BeginScene();
Math::Matrix persp;
- Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (600.0f) / (800.0f), 0.1f, 100.0f);
+ Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 100.0f);
device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp);
Math::Matrix id;
diff --git a/src/graphics/opengl/test/texture_test.cpp b/src/graphics/opengl/test/texture_test.cpp
index 03847fc..66ed770 100644
--- a/src/graphics/opengl/test/texture_test.cpp
+++ b/src/graphics/opengl/test/texture_test.cpp
@@ -40,8 +40,8 @@ void Init(Gfx::CGLDevice *device)
tex2CreateParams.magFilter = Gfx::TEX_MAG_FILTER_NEAREST;
tex2CreateParams.wrapS = Gfx::TEX_WRAP_CLAMP;
- Gfx::Texture* tex1 = device->CreateTexture(&img1, tex1CreateParams);
- Gfx::Texture* tex2 = device->CreateTexture(&img2, tex2CreateParams);
+ Gfx::Texture tex1 = device->CreateTexture(&img1, tex1CreateParams);
+ Gfx::Texture tex2 = device->CreateTexture(&img2, tex2CreateParams);
device->SetTexture(0, tex1);
device->SetTexture(1, tex2);
@@ -75,13 +75,13 @@ void Render(Gfx::CGLDevice *device)
static Gfx::VertexTex2 quad[] =
{
- Gfx::VertexTex2(Math::Vector(-2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 1.0f), Math::Point(0.0f, 1.0f)),
- Gfx::VertexTex2(Math::Vector( 2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 1.0f), Math::Point(1.0f, 1.0f)),
+ Gfx::VertexTex2(Math::Vector(-2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f)),
Gfx::VertexTex2(Math::Vector( 2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 0.0f), Math::Point(1.0f, 0.0f)),
+ Gfx::VertexTex2(Math::Vector( 2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 1.0f), Math::Point(1.0f, 1.0f)),
- Gfx::VertexTex2(Math::Vector( 2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 0.0f), Math::Point(1.0f, 0.0f)),
- Gfx::VertexTex2(Math::Vector(-2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f)),
+ Gfx::VertexTex2(Math::Vector( 2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 1.0f), Math::Point(1.0f, 1.0f)),
Gfx::VertexTex2(Math::Vector(-2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 1.0f), Math::Point(0.0f, 1.0f)),
+ Gfx::VertexTex2(Math::Vector(-2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f)),
};
Math::Matrix t;
diff --git a/src/graphics/opengl/test/transform_test.cpp b/src/graphics/opengl/test/transform_test.cpp
index 5982c4e..4decaa0 100644
--- a/src/graphics/opengl/test/transform_test.cpp
+++ b/src/graphics/opengl/test/transform_test.cpp
@@ -38,13 +38,13 @@ void Init(Gfx::CGLDevice *device)
device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, true);
device->SetShadeModel(Gfx::SHADE_SMOOTH);
}
-
+#include <GL/gl.h>
void Render(Gfx::CGLDevice *device)
{
device->BeginScene();
Math::Matrix persp;
- Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (600.0f) / (800.0f), 0.1f, 100.0f);
+ Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 100.0f);
device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp);
@@ -71,6 +71,8 @@ void Render(Gfx::CGLDevice *device)
Gfx::VertexCol line[2] = { Gfx::VertexCol() };
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
for (int x = -40; x <= 40; ++x)
{
line[0].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f);
diff --git a/src/math/geometry.h b/src/math/geometry.h
index 8954655..61d1868 100644
--- a/src/math/geometry.h
+++ b/src/math/geometry.h
@@ -284,26 +284,24 @@ inline void LoadViewMatrix(Math::Matrix &mat, const Math::Vector &from,
//! Loads a perspective projection matrix
/** \a fov field of view in radians
- \a aspect aspect ratio (height / width)
+ \a aspect aspect ratio (width / height)
\a nearPlane distance to near cut plane
\a farPlane distance to far cut plane */
-inline void LoadProjectionMatrix(Math::Matrix &mat, float fov = 1.570795f, float aspect = 1.0f,
+inline void LoadProjectionMatrix(Math::Matrix &mat, float fov = Math::PI / 2.0f, float aspect = 1.0f,
float nearPlane = 1.0f, float farPlane = 1000.0f)
{
assert(fabs(farPlane - nearPlane) >= 0.01f);
assert(fabs(sin(fov / 2)) >= 0.01f);
- float w = aspect * (cosf(fov / 2) / sinf(fov / 2));
- float h = 1.0f * (cosf(fov / 2) / sinf(fov / 2));
- float q = farPlane / (farPlane - nearPlane);
+ float f = cosf(fov / 2.0f) / sinf(fov / 2.0f);
mat.LoadZero();
- /* (1,1) */ mat.m[0 ] = w;
- /* (2,2) */ mat.m[5 ] = h;
- /* (3,3) */ mat.m[10] = q;
- /* (4,3) */ mat.m[11] = 1.0f;
- /* (3,4) */ mat.m[14] = -q * nearPlane;
+ /* (1,1) */ mat.m[0 ] = f / aspect;
+ /* (2,2) */ mat.m[5 ] = f;
+ /* (3,3) */ mat.m[10] = (nearPlane + farPlane) / (nearPlane - farPlane);
+ /* (4,3) */ mat.m[11] = -1.0f;
+ /* (3,4) */ mat.m[14] = (2.0f * farPlane * nearPlane) / (nearPlane - farPlane);
}
//! Loads an othogonal projection matrix
@@ -320,7 +318,7 @@ inline void LoadOrthoProjectionMatrix(Math::Matrix &mat, float left, float right
/* (3,3) */ mat.m[10] = -2.0f / (zFar - zNear);
/* (1,4) */ mat.m[12] = - (right + left) / (right - left);
- /* (2,4) */ mat.m[12] = - (top + bottom) / (top - bottom);
+ /* (2,4) */ mat.m[13] = - (top + bottom) / (top - bottom);
/* (3,4) */ mat.m[14] = - (zFar + zNear) / (zFar - zNear);
}