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
dev-ui
Piotr Dziwinski 2012-07-22 22:05:12 +02:00
parent 86ea086790
commit 8797569d33
22 changed files with 1495 additions and 575 deletions

View File

@ -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)
// To be sure no old event remains
m_private->currentEvent.type = SDL_NOEVENT;
bool haveEvent = true;
while (haveEvent)
{
SDL_PumpEvents();
count = SDL_PeepEvents(&m_private->currentEvent, 1, SDL_GETEVENT, SDL_ALLEVENTS);
}
else
{
SDL_PollEvent(&m_private->currentEvent);
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);
}
}
}
// If received an event
if ((m_active && count > 0) || (!m_active))
{
ParseEvent();
}
// 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
y: 0=down, 1=up
*/
Math::Point CApplication::WindowToInterfaceCoords(int x, int y)
/** 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)x / (float)m_private->deviceConfig.width,
1.0f - (float)y / (float)m_private->deviceConfig.height);
return Math::Point( (float)pos.x / (float)m_private->deviceConfig.width,
1.0f - (float)pos.y / (float)m_private->deviceConfig.height);
}
void CApplication::ParseEvent()
Math::IntPoint CApplication::InterfaceToWindowCoords(Math::Point pos)
{
return Math::IntPoint((int)(pos.x * m_private->deviceConfig.width),
(int)((1.0f - pos.y) * m_private->deviceConfig.height));
}
/** 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;
}

View File

@ -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();
//? void SetNiceMouse(bool nice);
//? bool GetNiceMouse();
//? bool GetNiceMouseCap();
//! Sets the visiblity of system mouse cursor
void SetSystemMouseVisible(bool visible);
//! Returns the visiblity of system mouse cursor
bool GetSystemMouseVisibile();
//! 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;
};

View File

@ -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;

View File

@ -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) {}
};

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}
};
/**

View File

@ -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;

View File

@ -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();
Math::Matrix view;
view.LoadIdentity();
m_device->SetTransform(Gfx::TRANSFORM_VIEW, view);
if (! Draw3DScene() )
return false;
Math::Matrix proj;
Math::LoadOrthoProjectionMatrix(proj, -10.0f, 10.0f, -10.0f, 10.0f);
m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, proj);
SetUpInterfaceView();
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))
};
m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, vertices, 3);
if (! DrawInterface() )
return false;
m_device->EndScene();
return true;
}
void Gfx::CEngine::SetUp3DView()
{
// TODO
}
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( 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);
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;
}

View File

@ -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;
enum ObjectType
EngineTriangle()
{
state = 0;
}
};
/**
\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
};
enum TriangleType
/**
\struct EngineObject
\brief Object drawn by the graphics engine */
struct EngineObject
{
//! triangles
TRIANGLE_TYPE_6T = 1,
//! surfaces
TRIANGLE_TYPE_6S = 2
//! 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;
}
};
enum Mapping
struct EngineObjLevel1;
struct EngineObjLevel2;
struct EngineObjLevel3;
struct EngineObjLevel4;
struct EngineObjLevel5;
/**
\struct EngineObjLevel5
\brief Tier 5 of object tree */
struct EngineObjLevel5
{
MAPPING_X = 1,
MAPPING_Y = 2,
MAPPING_Z = 3,
MAPPING_1X = 4,
MAPPING_1Y = 5,
MAPPING_1Z = 6
Gfx::Material material;
int state;
Gfx::EngineTriangleType type;
std::vector<Gfx::VertexTex2> vertices;
EngineObjLevel5();
};
enum MouseType
/**
\struct EngineObjLevel4
\brief Tier 4 of object tree */
struct EngineObjLevel4
{
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
int reserved;
std::vector<Gfx::EngineObjLevel5> up;
Gfx::EngineObjLevel3* down;
EngineObjLevel4();
};
enum ShadowType
/**
\struct EngineObjLevel3
\brief Tier 3 of object tree */
struct EngineObjLevel3
{
SHADOW_NORM = 0,
SHADOW_WORM = 1
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;
}
};
/**
\struct EngineGroundSpot
\brief A spot (large shadow) drawn on the ground by the graphics engine */
struct EngineGroundSpot
{
//! 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 EngineGroundMarkPhase
\brief Phase of life of an EngineGroundMark */
enum EngineGroundMarkPhase
{
//! Increase
ENG_GR_MARK_PHASE_INC = 1,
//! Fixed
ENG_GR_MARK_PHASE_FIX = 2,
//! Decrease
ENG_GR_MARK_PHASE_DEC = 2
};
/**
\struct EngineGroundMark
\brief A mark on ground drawn by the graphics engine */
struct EngineGroundMark
{
//! 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 EngineTextureMapping
\brief Type of texture mapping
*/
enum EngineTextureMapping
{
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
/**
\enum EngineMouseType
\brief Type of mouse cursor displayed in-game */
enum EngineMouseType
{
Gfx::VertexTex2 triangle[3];
Gfx::Material material;
int state;
char texName1[20];
char texName2[20];
//! 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 ObjLevel6
{
int totalPossible;
int totalUsed;
Gfx::Material material;
int state;
Gfx::TriangleType type;
Gfx::VertexTex2 vertex[1];
};
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 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
{
int totalPossible;
int totalUsed;
Gfx::ObjLevel2* table[1];
};
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
};
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,13 +490,13 @@ public:
bool AfterDeviceSetInit();
void SetTerrain(Gfx::CTerrain* terrain);
bool ProcessEvent(const Event &event);
bool Render();
void SetTerrain(Gfx::CTerrain* terrain);
bool WriteProfile();
void SetPause(bool pause);
@ -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);
bool FreeTexture(char* name);
bool LoadTexture(char* name, int stage=0);
bool LoadAllTexture();
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 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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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
};
};

View File

@ -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;

View File

@ -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(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, 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, 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, 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;

View File

@ -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);

View File

@ -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);
}