Merge branch 'dev-graphics' into dev

Documentation, rendering functions & fixes
dev-ui
Piotr Dziwinski 2012-08-13 23:13:10 +02:00
commit 8b2bca72dd
24 changed files with 661 additions and 525 deletions

View File

@ -149,6 +149,8 @@ bool CApplication::ParseArguments(int argc, char *argv[])
bool CApplication::Create() bool CApplication::Create()
{ {
GetLogger()->Info("Creating CApplication\n");
// TODO: verify that data directory exists // TODO: verify that data directory exists
// Temporarily -- only in windowed mode // Temporarily -- only in windowed mode
@ -161,6 +163,9 @@ bool CApplication::Create()
m_robotMain = new CRobotMain(m_iMan); */ m_robotMain = new CRobotMain(m_iMan); */
std::string standardInfoMessage =
"\nPlease see the console output or log file\n"
"to get more information on the source of error";
/* SDL initialization sequence */ /* SDL initialization sequence */
@ -169,18 +174,18 @@ bool CApplication::Create()
if (SDL_Init(initFlags) < 0) if (SDL_Init(initFlags) < 0)
{ {
SystemDialog( SDT_ERROR, "COLOBOT - Fatal Error", m_errorMessage = std::string("SDL initialization error:\n") +
"SDL initialization error:\n" + std::string(SDL_GetError());
std::string(SDL_GetError()) ); GetLogger()->Error(m_errorMessage.c_str());
m_exitCode = 2; m_exitCode = 2;
return false; return false;
} }
if ((IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) == 0) if ((IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) == 0)
{ {
SystemDialog( SDT_ERROR, "COLOBOT - Fatal Error", m_errorMessage = std::string("SDL_Image initialization error:\n") +
std::string("SDL_Image initialization error:\n") + std::string(IMG_GetError());
std::string(IMG_GetError()) ); GetLogger()->Error(m_errorMessage.c_str());
m_exitCode = 3; m_exitCode = 3;
return false; return false;
} }
@ -190,10 +195,10 @@ bool CApplication::Create()
if (m_private->surface == NULL) if (m_private->surface == NULL)
{ {
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", m_errorMessage = std::string("SDL error while setting video mode:\n") +
std::string("SDL error while setting video mode:\n") + std::string(SDL_GetError());
std::string(SDL_GetError()) ); GetLogger()->Error(m_errorMessage.c_str());
m_exitCode = 2; m_exitCode = 4;
return false; return false;
} }
@ -214,9 +219,8 @@ bool CApplication::Create()
m_device = new Gfx::CGLDevice(m_deviceConfig); m_device = new Gfx::CGLDevice(m_deviceConfig);
if (! m_device->Create() ) if (! m_device->Create() )
{ {
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", m_errorMessage = std::string("Error in CDevice::Create()\n") + standardInfoMessage;
std::string("Error in CDevice::Create()") ); m_exitCode = 5;
m_exitCode = 1;
return false; return false;
} }
@ -227,12 +231,13 @@ bool CApplication::Create()
if (! m_engine->Create() ) if (! m_engine->Create() )
{ {
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", m_errorMessage = std::string("Error in CEngine::Init()\n") + standardInfoMessage;
std::string("Error in CEngine::Init()") ); m_exitCode = 6;
m_exitCode = 1;
return false; return false;
} }
GetLogger()->Info("CApplication created successfully\n");
return true; return true;
} }
@ -241,10 +246,10 @@ bool CApplication::CreateVideoSurface()
const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
if (videoInfo == NULL) if (videoInfo == NULL)
{ {
SystemDialog( SDT_ERROR, "COLOBOT - Fatal Error", m_errorMessage = std::string("SDL error while getting video info:\n ") +
std::string("SDL error while getting video info:\n ") + std::string(SDL_GetError());
std::string(SDL_GetError()) ); GetLogger()->Error(m_errorMessage.c_str());
m_exitCode = 2; m_exitCode = 7;
return false; return false;
} }
@ -357,10 +362,11 @@ bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig)
{ {
if (! restore) if (! restore)
{ {
SystemDialog( SDT_ERROR, "COLOBT - Error", std::string error = std::string("SDL error while setting video mode:\n") +
std::string("SDL error while setting video mode:\n") +
std::string(SDL_GetError()) + std::string("\n") + std::string(SDL_GetError()) + std::string("\n") +
std::string("Previous mode will be restored") ); std::string("Previous mode will be restored");
GetLogger()->Error(error.c_str());
SystemDialog( SDT_ERROR, "COLOBT - Error", error);
restore = true; restore = true;
ChangeVideoConfig(m_lastDeviceConfig); ChangeVideoConfig(m_lastDeviceConfig);
@ -370,9 +376,10 @@ bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig)
{ {
restore = false; restore = false;
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", std::string error = std::string("SDL error while restoring previous video mode:\n") +
std::string("SDL error while restoring previous video mode:\n") + std::string(SDL_GetError());
std::string(SDL_GetError()) ); GetLogger()->Error(error.c_str());
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", error);
// Fatal error, so post the quit event // Fatal error, so post the quit event
@ -598,6 +605,11 @@ int CApplication::GetExitCode()
return m_exitCode; return m_exitCode;
} }
const std::string& CApplication::GetErrorMessage()
{
return m_errorMessage;
}
//! Translates SDL press state to PressState //! Translates SDL press state to PressState
PressState TranslatePressState(unsigned char state) PressState TranslatePressState(unsigned char state)
{ {

View File

@ -131,6 +131,9 @@ public:
//! Returns the code to be returned at main() exit //! Returns the code to be returned at main() exit
int GetExitCode(); int GetExitCode();
//! Returns the message of error (set to something if exit code is not 0)
const std::string& GetErrorMessage();
//! Cleans up before exit //! Cleans up before exit
void Destroy(); void Destroy();
@ -234,6 +237,9 @@ protected:
//! Whether debug mode is enabled //! Whether debug mode is enabled
bool m_debugMode; bool m_debugMode;
//! Message to be displayed as error to the user
std::string m_errorMessage;
//! Current configuration of OpenGL display device //! Current configuration of OpenGL display device
Gfx::GLDeviceConfig m_deviceConfig; Gfx::GLDeviceConfig m_deviceConfig;
//! Previous configuration of OpenGL display device //! Previous configuration of OpenGL display device

View File

@ -80,7 +80,7 @@ int main(int argc, char *argv[])
if (! app.ParseArguments(argc, argv)) if (! app.ParseArguments(argc, argv))
{ {
SystemDialog(SDT_ERROR, "COLOBOT", "Invalid commandline arguments!\n"); SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
return app.GetExitCode(); return app.GetExitCode();
} }
@ -90,6 +90,10 @@ int main(int argc, char *argv[])
{ {
app.Destroy(); // ensure a clean exit app.Destroy(); // ensure a clean exit
code = app.GetExitCode(); code = app.GetExitCode();
if ( code != 0 && !app.GetErrorMessage().empty() )
{
SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app.GetErrorMessage());
}
logger.Info("Didn't run main loop. Exiting with code %d\n", code); logger.Info("Didn't run main loop. Exiting with code %d\n", code);
return code; return code;
} }

View File

@ -642,7 +642,7 @@ enum ActiveEventFlags
struct ActiveEventData struct ActiveEventData
{ {
//! Flags (bitmask of enum values ActiveEventFlags) //! Flags (bitmask of enum values ActiveEventFlags)
unsigned char flags = 0; unsigned char flags;
//! True if the focus was gained; false otherwise //! True if the focus was gained; false otherwise
bool gain; bool gain;

View File

@ -286,9 +286,6 @@ public:
//! Destroys the device, releasing every acquired resource //! Destroys the device, releasing every acquired resource
virtual void Destroy() = 0; virtual void Destroy() = 0;
//! Returns the last encountered error
virtual std::string GetError() = 0;
//! Begins drawing the 3D scene //! Begins drawing the 3D scene
virtual void BeginScene() = 0; virtual void BeginScene() = 0;
//! Ends drawing the 3D scene //! Ends drawing the 3D scene

View File

@ -20,6 +20,7 @@
#include "graphics/engine/cloud.h" #include "graphics/engine/cloud.h"
#include "common/iman.h" #include "common/iman.h"
#include "graphics/core/device.h"
#include "graphics/engine/engine.h" #include "graphics/engine/engine.h"
#include "graphics/engine/terrain.h" #include "graphics/engine/terrain.h"
#include "math/geometry.h" #include "math/geometry.h"
@ -94,112 +95,96 @@ void Gfx::CCloud::AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep,
void Gfx::CCloud::Draw() void Gfx::CCloud::Draw()
{ {
/* TODO! if (! m_enable) return;
LPDIRECT3DDEVICE7 device; if (m_level == 0.0f) return;
D3DVERTEX2* vertex; if (m_lines.empty()) return;
Math::Matrix* matView;
D3DMATERIAL7 material;
Math::Matrix matrix;
Math::Vector n, pos, p, eye;
Math::Point uv1, uv2;
float iDeep, deep, size, fogStart, fogEnd;
int i, j, u;
if ( !m_enable ) return; std::vector<Gfx::VertexTex2> vertices((m_brick+2)*2, Gfx::VertexTex2());
if ( m_level == 0.0f ) return;
if ( m_linesUsed == 0 ) return;
vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2); float iDeep = m_engine->GetDeepView();
float deep = (m_brick*m_size)/2.0f;
iDeep = m_engine->GetDeepView();
deep = (m_brick*m_size)/2.0f;
m_engine->SetDeepView(deep); m_engine->SetDeepView(deep);
m_engine->SetFocus(m_engine->GetFocus()); m_engine->SetFocus(m_engine->GetFocus());
m_engine->UpdateMatProj(); // increases the depth of view m_engine->UpdateMatProj(); // increases the depth of view
fogStart = deep*0.15f; float fogStart = deep*0.15f;
fogEnd = deep*0.24f; float fogEnd = deep*0.24f;
device = m_engine->GetD3DDevice(); Gfx::CDevice* device = m_engine->GetDevice();
device->SetRenderState(D3DRENDERSTATE_AMBIENT, 0x00000000);
device->SetRenderState(D3DRENDERSTATE_LIGHTING, false);
device->SetRenderState(D3DRENDERSTATE_ZENABLE, false);
device->SetRenderState(D3DRENDERSTATE_FOGENABLE, true);
device->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(fogStart));
device->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(fogEnd));
matView = m_engine->GetMatView(); // TODO: do this better?
{ device->SetFogParams(Gfx::FOG_LINEAR, m_engine->GetFogColor( m_engine->GetRankView() ),
D3DMATRIX mat = MAT_TO_D3DMAT(*matView); fogStart, fogEnd, 1.0f);
device->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat);
}
ZeroMemory( &material, sizeof(D3DMATERIAL7) ); device->SetTransform(Gfx::TRANSFORM_VIEW, m_engine->GetMatView());
Gfx::Material material;
material.diffuse = m_diffuse; material.diffuse = m_diffuse;
material.ambient = m_ambient; material.ambient = m_ambient;
m_engine->SetMaterial(material); m_engine->SetMaterial(material);
m_engine->SetTexture(m_filename, 0); m_engine->SetTexture(m_fileName, 0);
m_engine->SetTexture(m_filename, 1); m_engine->SetTexture(m_fileName, 1);
m_engine->SetState(D3DSTATETTb|D3DSTATEFOG|D3DSTATEWRAP); m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK | Gfx::ENG_RSTATE_FOG | Gfx::ENG_RSTATE_WRAP);
Math::Matrix matrix;
matrix.LoadIdentity(); matrix.LoadIdentity();
{ device->SetTransform(Gfx::TRANSFORM_WORLD, matrix);
D3DMATRIX mat = MAT_TO_D3DMAT(matrix);
device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
}
size = m_size/2.0f; float size = m_size/2.0f;
eye = m_engine->GetEyePt(); Math::Vector eye = m_engine->GetEyePt();
n = Math::Vector(0.0f, -1.0f, 0.0f); Math::Vector n = Math::Vector(0.0f, -1.0f, 0.0f);
// Draws all the lines. // Draws all the lines
for ( i=0 ; i<m_linesUsed ; i++ ) for (int i = 0; i < static_cast<int>( m_lines.size() ); i++)
{ {
Math::Vector pos;
pos.y = m_level; pos.y = m_level;
pos.z = m_lines[i].pz; pos.z = m_lines[i].pz;
pos.x = m_lines[i].px1; pos.x = m_lines[i].px1;
u = 0; int vertexIndex = 0;
Math::Vector p;
Math::Point uv1, uv2;
p.x = pos.x-size; p.x = pos.x-size;
p.z = pos.z+size; p.z = pos.z+size;
p.y = pos.y; p.y = pos.y;
AdjustLevel(p, eye, deep, uv1, uv2); AdjustLevel(p, eye, deep, uv1, uv2);
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
p.x = pos.x-size; p.x = pos.x-size;
p.z = pos.z-size; p.z = pos.z-size;
p.y = pos.y; p.y = pos.y;
AdjustLevel(p, eye, deep, uv1, uv2); AdjustLevel(p, eye, deep, uv1, uv2);
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
for ( j=0 ; j<m_lines[i].len ; j++ ) for (int j = 0; j < m_lines[i].len; j++)
{ {
p.x = pos.x+size; p.x = pos.x+size;
p.z = pos.z+size; p.z = pos.z+size;
p.y = pos.y; p.y = pos.y;
AdjustLevel(p, eye, deep, uv1, uv2); AdjustLevel(p, eye, deep, uv1, uv2);
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
p.x = pos.x+size; p.x = pos.x+size;
p.z = pos.z-size; p.z = pos.z-size;
p.y = pos.y; p.y = pos.y;
AdjustLevel(p, eye, deep, uv1, uv2); AdjustLevel(p, eye, deep, uv1, uv2);
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
pos.x += size*2.0f; pos.x += size*2.0f;
} }
device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL); device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, &vertices[0], vertexIndex);
m_engine->AddStatisticTriangle(u-2); m_engine->AddStatisticTriangle(vertexIndex - 2);
} }
m_engine->SetDeepView(iDeep); m_engine->SetDeepView(iDeep);
m_engine->SetFocus(m_engine->GetFocus()); m_engine->SetFocus(m_engine->GetFocus());
m_engine->UpdateMatProj(); // gives depth to initial m_engine->UpdateMatProj(); // gives depth to initial
free(vertex); */
} }
void Gfx::CCloud::CreateLine(int x, int y, int len) void Gfx::CCloud::CreateLine(int x, int y, int len)

View File

@ -40,12 +40,19 @@ namespace Gfx {
class CEngine; class CEngine;
class CTerrain; class CTerrain;
/**
* \struct CloudLine
* \brief Cloud strip
*/
struct CloudLine struct CloudLine
{ {
//! Beginning //@{
//! Beginning (terrain coordinates)
short x, y; short x, y;
//! In length x //@}
//! Length in X direction (terrain coordinates)
short len; short len;
//! X (1, 2) and Z coordinates (world coordinates)
float px1, px2, pz; float px1, px2, pz;
CloudLine() CloudLine()
@ -57,6 +64,15 @@ struct CloudLine
}; };
/**
* \class CCloud
* \brief Cloud layer renderer
*
* Renders the cloud layer as fog. Cloud layer is similar to water layer
* - it occurs only at specified level of terrain. Cloud map is created
* the same way water is created. CloudLine structs are used to specify
* lines in X direction in XY terrain coordinates.
*/
class CCloud class CCloud
{ {
public: public:

View File

@ -946,7 +946,7 @@ bool Gfx::CEngine::AddQuick(int objRank, const Gfx::EngineObjLevel4& buffer,
if (buffer.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES) if (buffer.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES)
m_objects[objRank].totalTriangles += buffer.vertices.size() / 3; m_objects[objRank].totalTriangles += buffer.vertices.size() / 3;
else // surfaces else if (buffer.type == Gfx::ENG_TRIANGLE_TYPE_SURFACE)
m_objects[objRank].totalTriangles += buffer.vertices.size() - 2; m_objects[objRank].totalTriangles += buffer.vertices.size() - 2;
return true; return true;
@ -2113,8 +2113,7 @@ Gfx::Texture Gfx::CEngine::CreateTexture(const std::string& texName, const Gfx::
if (! img.Load(m_app->GetDataFilePath(m_texPath, texName))) if (! img.Load(m_app->GetDataFilePath(m_texPath, texName)))
{ {
std::string error = img.GetError(); std::string error = img.GetError();
GetLogger()->Error("Couldn't load texture '%s': %s\n", texName.c_str(), error.c_str()); GetLogger()->Error("Couldn't load texture '%s': %s, blacklisting\n", texName.c_str(), error.c_str());
GetLogger()->Error("Blacklisting texture '%s'\n", texName.c_str());
m_texBlacklist.insert(texName); m_texBlacklist.insert(texName);
return Gfx::Texture(); // invalid texture return Gfx::Texture(); // invalid texture
} }
@ -2123,9 +2122,7 @@ Gfx::Texture Gfx::CEngine::CreateTexture(const std::string& texName, const Gfx::
if (! tex.Valid()) if (! tex.Valid())
{ {
std::string error = m_device->GetError(); GetLogger()->Error("Couldn't load texture '%s', blacklisting\n", texName.c_str());
GetLogger()->Error("Couldn't load texture '%s': %s\n", texName.c_str(), error.c_str());
GetLogger()->Error("Blacklisting texture '%s'\n", texName.c_str());
m_texBlacklist.insert(texName); m_texBlacklist.insert(texName);
return tex; return tex;
} }
@ -2203,13 +2200,15 @@ bool Gfx::CEngine::LoadAllTextures()
if (! p1.tex1Name.empty()) if (! p1.tex1Name.empty())
{ {
if (! LoadTexture(p1.tex1Name).Valid()) p1.tex1 = LoadTexture(p1.tex1Name);
if (! p1.tex1.Valid())
ok = false; ok = false;
} }
if (! p1.tex2Name.empty()) if (! p1.tex2Name.empty())
{ {
if (! LoadTexture(p1.tex2Name).Valid()) p1.tex2 = LoadTexture(p1.tex2Name);
if (! p1.tex2.Valid())
ok = false; ok = false;
} }
} }
@ -2865,15 +2864,6 @@ void Gfx::CEngine::Render()
void Gfx::CEngine::Draw3DScene() void Gfx::CEngine::Draw3DScene()
{ {
/* TODO!
D3DObjLevel1* p1;
D3DObjLevel2* p2;
D3DObjLevel3* p3;
D3DObjLevel4* p4;
D3DObjLevel5* p5;
D3DVERTEX2* pv;
int l1, l2, l3, l4, l5, objRank;*/
if (m_groundSpotVisible) if (m_groundSpotVisible)
UpdateGroundSpotTextures(); UpdateGroundSpotTextures();
@ -2899,144 +2889,144 @@ void Gfx::CEngine::Draw3DScene()
if (m_shadowVisible) if (m_shadowVisible)
{ {
// Draw the field // Draw the terrain
// TODO!
/* for (int l1 = 0; l1 < static_cast<int>( m_objectTree.size() ); l1++)
p1 = m_objectPointer;
for ( l1=0 ; l1<p1->totalUsed ; l1++ )
{ {
p2 = p1->table[l1]; Gfx::EngineObjLevel1& p1 = m_objectTree[l1];
if ( p2 == 0 ) continue; if (! p1.used) continue;
SetTexture(p2->tex1Name, 0);
SetTexture(p2->tex2Name, 1); // Should be loaded by now
for ( l2=0 ; l2<p2->totalUsed ; l2++ ) SetTexture(p1.tex1, 0);
SetTexture(p1.tex2, 1);
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
p3 = p2->table[l2]; Gfx::EngineObjLevel2& p2 = p1.next[l2];
if ( p3 == 0 ) continue; if (! p2.used) continue;
objRank = p3->objRank;
if ( m_objects[objRank].type != TYPETERRAIN ) continue;
if ( !m_objects[objRank].bDrawWorld ) continue;
{ int objRank = p2.objRank;
D3DMATRIX mat = MAT_TO_D3DMAT(m_objects[objRank].transform); if (m_objects[objRank].type != Gfx::ENG_OBJTYPE_TERRAIN)
m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); continue;
} if (! m_objects[objRank].drawWorld)
continue;
if ( !IsVisible(objRank) ) continue; for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
m_light->LightUpdate(m_objects[objRank].type);
for ( l3=0 ; l3<p3->totalUsed ; l3++ )
{ {
p4 = p3->table[l3]; Gfx::EngineObjLevel3& p3 = p2.next[l1];
if ( p4 == 0 ) continue; if (! p3.used) continue;
if ( m_objects[objRank].distance < p4->min ||
m_objects[objRank].distance >= p4->max ) continue; if ( m_objects[objRank].distance < p3.min ||
for ( l4=0 ; l4<p4->totalUsed ; l4++ ) m_objects[objRank].distance >= p3.max ) continue;
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{ {
p5 = p4->table[l4]; Gfx::EngineObjLevel4& p4 = p3.next[l4];
if ( p5 == 0 ) continue; if (! p4.used) continue;
for ( l5=0 ; l5<p5->totalUsed ; l5++ )
SetMaterial(p4.material);
SetState(p4.state);
if (p4.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES)
{ {
p6 = p5->table[l5]; m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLES,
if ( p6 == 0 ) continue; &p4.vertices[0],
SetMaterial(p6->material); p4.vertices.size() );
SetState(p6->state); m_statisticTriangle += p4.vertices.size() / 3;
if ( p6->type == D3DTYPE6T )
{
pv = &p6->vertex[0];
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,
D3DFVF_VERTEX2,
pv, p6->totalUsed,
NULL);
m_statisticTriangle += p6->totalUsed/3;
}
if ( p6->type == D3DTYPE6S )
{
pv = &p6->vertex[0];
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
D3DFVF_VERTEX2,
pv, p6->totalUsed,
NULL);
m_statisticTriangle += p6->totalUsed-2;
}
} }
} if (p4.type == Gfx::ENG_TRIANGLE_TYPE_SURFACE)
}
}
}*/
// Draws the shadows
DrawShadow();
}
// Draw objects
bool transparent = false;
/* TODO!
p1 = m_objectPointer;
for ( l1=0 ; l1<p1->totalUsed ; l1++ )
{
p2 = p1->table[l1];
if ( p2 == 0 ) continue;
SetTexture(p2->tex1Name, 0);
SetTexture(p2->tex2Name, 1);
for ( l2=0 ; l2<p2->totalUsed ; l2++ )
{
p3 = p2->table[l2];
if ( p3 == 0 ) continue;
objRank = p3->objRank;
if ( m_bShadow && m_objects[objRank].type == TYPETERRAIN ) continue;
if ( !m_objects[objRank].bDrawWorld ) continue;
{
D3DMATRIX mat = MAT_TO_D3DMAT(m_objects[objRank].transform);
m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
}
if ( !IsVisible(objRank) ) continue;
m_light->LightUpdate(m_objects[objRank].type);
for ( l3=0 ; l3<p3->totalUsed ; l3++ )
{
p4 = p3->table[l3];
if ( p4 == 0 ) continue;
if ( m_objects[objRank].distance < p4->min ||
m_objects[objRank].distance >= p4->max ) continue;
for ( l4=0 ; l4<p4->totalUsed ; l4++ )
{
p5 = p4->table[l4];
if ( p5 == 0 ) continue;
for ( l5=0 ; l5<p5->totalUsed ; l5++ )
{
p6 = p5->table[l5];
if ( p6 == 0 ) continue;
SetMaterial(p6->material);
if ( m_objects[objRank].transparency != 0.0f ) // transparent ?
{ {
transparent = true; m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLE_STRIP,
continue; &p4.vertices[0],
} p4.vertices.size() );
SetState(p6->state); m_statisticTriangle += p4.vertices.size() - 2;
if ( p6->type == D3DTYPE6T )
{
pv = &p6->vertex[0];
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,
D3DFVF_VERTEX2,
pv, p6->totalUsed,
NULL);
m_statisticTriangle += p6->totalUsed/3;
}
if ( p6->type == D3DTYPE6S )
{
pv = &p6->vertex[0];
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
D3DFVF_VERTEX2,
pv, p6->totalUsed,
NULL);
m_statisticTriangle += p6->totalUsed-2;
} }
} }
} }
} }
} }
}*/
// Draws the shadows
DrawShadow();
}
// Draw objects (non-terrain)
bool transparent = false;
for (int l1 = 0; l1 < static_cast<int>( m_objectTree.size() ); l1++)
{
Gfx::EngineObjLevel1& p1 = m_objectTree[l1];
if (! p1.used) continue;
// Should be loaded by now
SetTexture(p1.tex1, 0);
SetTexture(p1.tex2, 1);
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
Gfx::EngineObjLevel2& p2 = p1.next[l2];
if (! p2.used) continue;
int objRank = p2.objRank;
if (m_shadowVisible && m_objects[objRank].type == Gfx::ENG_OBJTYPE_TERRAIN)
continue;
if (! m_objects[objRank].drawWorld)
continue;
m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_objects[objRank].transform);
if (! IsVisible(objRank))
continue;
m_lightMan->UpdateLightsEnableState(m_objects[objRank].type);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
Gfx::EngineObjLevel3& p3 = p2.next[l1];
if (! p3.used) continue;
if ( m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max ) continue;
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
Gfx::EngineObjLevel4& p4 = p3.next[l4];
if (! p4.used) continue;
if (m_objects[objRank].transparency != 0.0f) // transparent ?
{
transparent = true;
continue;
}
SetMaterial(p4.material);
SetState(p4.state);
if (p4.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES)
{
m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLES,
&p4.vertices[0],
p4.vertices.size() );
m_statisticTriangle += p4.vertices.size() / 3;
}
else if (p4.type == Gfx::ENG_TRIANGLE_TYPE_SURFACE)
{
m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLE_STRIP,
&p4.vertices[0],
p4.vertices.size() );
m_statisticTriangle += p4.vertices.size() - 2;
}
}
}
}
}
// Draw transparent objects
if (transparent) if (transparent)
{ {
@ -3053,70 +3043,73 @@ void Gfx::CEngine::Draw3DScene()
tColor = Gfx::Color(136.0f / 255.0f, 136.0f / 255.0f, 136.0f / 255.0f, 136.0f / 255.0f); tColor = Gfx::Color(136.0f / 255.0f, 136.0f / 255.0f, 136.0f / 255.0f, 136.0f / 255.0f);
} }
// Draw transparent objects. for (int l1 = 0; l1 < static_cast<int>( m_objectTree.size() ); l1++)
/* TODO!
p1 = m_objectPointer;
for ( l1=0 ; l1<p1->totalUsed ; l1++ )
{ {
p2 = p1->table[l1]; Gfx::EngineObjLevel1& p1 = m_objectTree[l1];
if ( p2 == 0 ) continue; if (! p1.used) continue;
SetTexture(p2->tex1Name, 0);
SetTexture(p2->tex2Name, 1); // Should be loaded by now
for ( l2=0 ; l2<p2->totalUsed ; l2++ ) SetTexture(p1.tex1, 0);
SetTexture(p1.tex2, 1);
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
p3 = p2->table[l2]; Gfx::EngineObjLevel2& p2 = p1.next[l2];
if ( p3 == 0 ) continue; if (! p2.used) continue;
objRank = p3->objRank;
if ( m_bShadow && m_objects[objRank].type == TYPETERRAIN ) continue;
if ( !m_objects[objRank].bDrawWorld ) continue;
{ int objRank = p2.objRank;
D3DMATRIX mat = MAT_TO_D3DMAT(m_objects[objRank].transform);
m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
}
if ( !IsVisible(objRank) ) continue; if (m_shadowVisible && m_objects[objRank].type == Gfx::ENG_OBJTYPE_TERRAIN)
m_light->LightUpdate(m_objects[objRank].type); continue;
for ( l3=0 ; l3<p3->totalUsed ; l3++ )
if (! m_objects[objRank].drawWorld)
continue;
m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_objects[objRank].transform);
if (! IsVisible(objRank))
continue;
m_lightMan->UpdateLightsEnableState(m_objects[objRank].type);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
p4 = p3->table[l3]; Gfx::EngineObjLevel3& p3 = p2.next[l1];
if ( p4 == 0 ) continue; if (! p3.used) continue;
if ( m_objects[objRank].distance < p4->min ||
m_objects[objRank].distance >= p4->max ) continue; if ( m_objects[objRank].distance < p3.min ||
for ( l4=0 ; l4<p4->totalUsed ; l4++ ) m_objects[objRank].distance >= p3.max ) continue;
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{ {
p5 = p4->table[l4]; Gfx::EngineObjLevel4& p4 = p3.next[l4];
if ( p5 == 0 ) continue; if (! p4.used) continue;
for ( l5=0 ; l5<p5->totalUsed ; l5++ )
if (m_objects[objRank].transparency == 0.0f)
continue;
SetMaterial(p4.material);
SetState(tState, tColor);
if (p4.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES)
{ {
p6 = p5->table[l5]; m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLES,
if ( p6 == 0 ) continue; &p4.vertices[0],
SetMaterial(p6->material); p4.vertices.size() );
if ( m_objects[objRank].transparency == 0.0f ) continue;
SetState(tState, tColor); m_statisticTriangle += p4.vertices.size() / 3;
if ( p6->type == D3DTYPE6T ) }
{ else if (p4.type == Gfx::ENG_TRIANGLE_TYPE_SURFACE)
pv = &p6->vertex[0]; {
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLE_STRIP,
D3DFVF_VERTEX2, &p4.vertices[0],
pv, p6->totalUsed, p4.vertices.size() );
NULL); m_statisticTriangle += p4.vertices.size() - 2;
m_statisticTriangle += p6->totalUsed/3;
}
if ( p6->type == D3DTYPE6S )
{
pv = &p6->vertex[0];
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
D3DFVF_VERTEX2,
pv, p6->totalUsed,
NULL);
m_statisticTriangle += p6->totalUsed-2;
}
} }
} }
} }
} }
} */ }
} }
m_lightMan->UpdateLightsEnableState(Gfx::ENG_OBJTYPE_TERRAIN); m_lightMan->UpdateLightsEnableState(Gfx::ENG_OBJTYPE_TERRAIN);
@ -3165,68 +3158,70 @@ void Gfx::CEngine::DrawInterface()
m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matView); m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matView);
// TODO! for (int l1 = 0; l1 < static_cast<int>( m_objectTree.size() ); l1++)
/*
for (int l1 = 0; l1 < m_objectTree.size(); l1++)
{ {
Gfx::EngineObjLevel1* p1 = &m_objectTree[l1]; Gfx::EngineObjLevel1& p1 = m_objectTree[l1];
p2 = p1->table[l1]; if (! p1.used) continue;
if ( p2 == 0 ) continue;
SetTexture(p2->tex1Name, 0); // Should be loaded by now
SetTexture(p2->tex2Name, 1); SetTexture(p1.tex1, 0);
for ( l2=0 ; l2<p2->totalUsed ; l2++ ) SetTexture(p1.tex2, 1);
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
p3 = p2->table[l2]; Gfx::EngineObjLevel2& p2 = p1.next[l2];
if ( p3 == 0 ) continue; if (! p2.used) continue;
objRank = p3->objRank;
if ( !m_objects[objRank].bDrawFront ) continue;
{ int objRank = p2.objRank;
D3DMATRIX mat = MAT_TO_D3DMAT(m_objects[objRank].transform);
m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
}
if ( !IsVisible(objRank) ) continue; if (m_shadowVisible && m_objects[objRank].type == Gfx::ENG_OBJTYPE_TERRAIN)
m_light->LightUpdate(m_objects[objRank].type); continue;
for ( l3=0 ; l3<p3->totalUsed ; l3++ )
if (! m_objects[objRank].drawFront)
continue;
m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_objects[objRank].transform);
if (! IsVisible(objRank))
continue;
m_lightMan->UpdateLightsEnableState(m_objects[objRank].type);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
p4 = p3->table[l3]; Gfx::EngineObjLevel3& p3 = p2.next[l1];
if ( p4 == 0 ) continue; if (! p3.used) continue;
if ( m_objects[objRank].distance < p4->min ||
m_objects[objRank].distance >= p4->max ) continue; if ( m_objects[objRank].distance < p3.min ||
for ( l4=0 ; l4<p4->totalUsed ; l4++ ) m_objects[objRank].distance >= p3.max ) continue;
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{ {
p5 = p4->table[l4]; Gfx::EngineObjLevel4& p4 = p3.next[l4];
if ( p5 == 0 ) continue; if (! p4.used) continue;
for ( l5=0 ; l5<p5->totalUsed ; l5++ )
SetMaterial(p4.material);
SetState(p4.state);
if (p4.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES)
{ {
p6 = p5->table[l5]; m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLES,
if ( p6 == 0 ) continue; &p4.vertices[0],
SetMaterial(p6->material); p4.vertices.size() );
SetState(p6->state);
if ( p6->type == D3DTYPE6T ) m_statisticTriangle += p4.vertices.size() / 3;
{ }
pv = &p6->vertex[0]; else if (p4.type == Gfx::ENG_TRIANGLE_TYPE_SURFACE)
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, {
D3DFVF_VERTEX2, m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLE_STRIP,
pv, p6->totalUsed, &p4.vertices[0],
NULL); p4.vertices.size() );
m_statisticTriangle += p6->totalUsed/3; m_statisticTriangle += p4.vertices.size() - 2;
}
if ( p6->type == D3DTYPE6S )
{
pv = &p6->vertex[0];
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
D3DFVF_VERTEX2,
pv, p6->totalUsed,
NULL);
m_statisticTriangle += p6->totalUsed-2;
}
} }
} }
} }
} }
}*/ }
m_particle->DrawParticle(Gfx::SH_FRONT); // draws the particles of the 3D world m_particle->DrawParticle(Gfx::SH_FRONT); // draws the particles of the 3D world

View File

@ -539,24 +539,95 @@ struct EngineMouse
/** /**
\class CEngine * \class CEngine
\brief The graphics engine * \brief The graphics engine
*
This is the main class for graphics engine. It is responsible for drawing the 3D scene, * 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. * setting various render states, and facilitating the drawing of 2D interface.
*
It uses a lower-level CDevice object which is implementation-independent core engine. * It uses a lower-level CDevice object which is implementation-independent core engine.
*
\section Objecs Engine objects * \section 3DScene 3D Scene
*
The 3D scene is composed of objects which are basically collections of triangles forming * The 3D scene is drawn with view coordinates set from camera position in 3D space and
a surface or simply independent triangles in space. Objects are stored in the engine * a perspective projection matrix. The world matrix depends on the object drawn.
as a tree structure which is composed of 4 tiers (EngineObjLevel1, EngineObjLevel2 and so on). * The coordinate system is left-handed: X axis is to the right, Y axis to the top and Z axis
Each tier stores some data about object triangle, like textures or materials used. * is into the screen (Z = 0 is the sceen surface).
Additional information on objects stored are in EngineObject structure. *
Each object is uniquely identified by its rank. * In general, the 3D scene is composed of the following things:
* - sky background (gradient or texture image)
... * - planets orbiting in the sky (drawn by CPlanet)
* - terrain - ground of the game level (part of engine objects)
* - main scene objects - robots, buildings, etc. (engine objects)
* - water/lava (drawn by CWater)
* - cloud layer (drawn by CCloud)
* - fire, lightning and particle effects (CPyro, CLightning and CParticle)
* - foreground image overlaid onto the scene at the end - for example, aiming crosshairs
* - 2D interface controls available in-game
* - mouse cursor
* - animated highlight box of the selected object(s)
*
* \section 2DInterface 2D Interface
*
* The 2D interface is drawn in fixed XY coordinates, independent from window size.
* Lower-left corner of the screen is (0,0) and upper-right corner is (1,1).
* Matrices for world, view and projection are therefore fixed and never change.
*
* The class tracks the change of window coordinates and conversion functions
* between the window and interface coordinates are provided.
*
* Interface drawing is delegated to CInterface class and particular controls
* are instances of CControl class. The source code for these classes is in
* src/ui directory.
*
* \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 uniquely identified by object rank obtained at object creation. Creating an
* object equals to allocating space for EngineObject structure which holds object parameters.
* Object's geometric data is stored in a separate structure - a 4-tier tree which splits
* the information of each geometric triangle.
*
* The 4 tiers contain the following information:
* - level 1 (EngineObjLevel1) - two textures (names and structs) applied to triangles,
* - level 2 (EngineObjLevel2) - object rank
* - level 3 (EngineObjLevel3) - minumum and maximum LOD (=level of detail)
* - level 4 (EngineObjLevel4) - type of object*, material, render state and the actual triangle data
*
* NOTE: type of object in this context means only the internal type in 3D engine. It is not related
* to CObject types.
*
* Such tiered structure complicates loops over all object data, but saves a lot of memory and
* optimizes the rendering process (for instance, switching of textures is an expensive operation).
*
* \section Shadows Shadows
*
* Each engine object can be associated with a shadow (EngineShadow). Like objects, shadows are
* identified by their rank obtained upon creation.
*
* ...
*
* \section RenderStates Render States
*
* Almost every primitive drawn on screen is drawn in state set through EngineRenderState enum.
* In some functions, custom modes are still set, using CDevice's SetRenderState. However, it
* will be subject to removal in the future. Generally, setting render states should be minimized
* to avoid unnecessary overhead.
*
* Some states are clearly the result of legacy drawing and texturing methods. For example, TTEXTURE
* states should really be removed and the textures changed to ones with alpha channel. In the future,
* the whole modesetting code will probably be refactored to something more maintainable.
*
* \section Textures Textures
*
* Textures are loaded from a texture subdir in data directory. In the old code, textures were identified
* by file name and loaded using some D3D util code. With new code and OpenGL backend, this approach is not
* efficient - name comparison, etc. takes a lot of time. In the future, textures should be loaded once
* at object creation time, and then referenced to as Gfx::Texture structs, or even as unsigned int ID's
* which is what OpenGL actually wants. The old method is kept for now, with mapping between texture names
* and texture structs but it will also be subject to refactoring in the future.
*/ */
class CEngine class CEngine
{ {

View File

@ -47,7 +47,12 @@ enum BlitzPhase
BPH_BLITZ, BPH_BLITZ,
}; };
/**
* \class CLightning
* \brief Lightning effect renderer
*
* Functions are only stubs for now.
*/
class CLightning class CLightning
{ {
public: public:

View File

@ -723,25 +723,18 @@ bool Gfx::CModelFile::ReadDXF(std::istream &stream, float min, float max)
bool Gfx::CModelFile::CreateEngineObject(int objRank, int addState) bool Gfx::CModelFile::CreateEngineObject(int objRank, int addState)
{ {
/*char texName1[20]; for (int i = 0; i < static_cast<int>( m_triangles.size() ); i++)
char texName2[20];
int texNum, i, state;
for (int i = 0; i < m_trianglesUsed; i++)
{ {
if (! m_triangles[i].used) continue; int state = m_triangles[i].state;
state = m_triangles[i].state; /* TODO ???
strcpy(texName1, m_triangles[i].texName); if (texName1 == "plant.png")
texName2[0] = 0; state |= Gfx::ENG_RSTATE_ALPHA;
if ( strcmp(texName1, "plant.tga") == 0 ) // ??? if (m_triangles[i].tex2Name.empty())
{ {
state |= D3DSTATEALPHA; int texNum = 0;
}
if ( m_triangles[i].texNum2 != 0 )
{
if ( m_triangles[i].texNum2 == 1 ) if ( m_triangles[i].texNum2 == 1 )
{ {
texNum = m_engine->RetSecondTexture(); texNum = m_engine->RetSecondTexture();
@ -760,15 +753,22 @@ bool Gfx::CModelFile::CreateEngineObject(int objRank, int addState)
state |= D3DSTATEDUALw; state |= D3DSTATEDUALw;
} }
sprintf(texName2, "dirty%.2d.tga", texNum); // ??? sprintf(texName2, "dirty%.2d.tga", texNum); // ???
} }*/
std::vector<Gfx::VertexTex2> vs;
vs.push_back(m_triangles[i].p1);
vs.push_back(m_triangles[i].p2);
vs.push_back(m_triangles[i].p3);
m_engine->AddTriangles(objRank, vs,
m_triangles[i].material,
state + addState,
m_triangles[i].tex1Name,
m_triangles[i].tex2Name,
m_triangles[i].min,
m_triangles[i].max, false);
}
m_engine->AddTriangle(objRank, &m_triangles[i].p1, 3,
m_triangles[i].material,
state + addState,
texName1, texName2,
m_triangles[i].min,
m_triangles[i].max, false);
}*/
return true; return true;
} }

View File

@ -256,7 +256,12 @@ struct WheelTrace
}; };
/**
* \class CParticle
* \brief Particle engine
*
* Functions are only stubs for now.
*/
class CParticle class CParticle
{ {
public: public:

View File

@ -35,6 +35,10 @@ namespace Gfx {
class CEngine; class CEngine;
/**
* \struct Planet
* \brief Planet texture definition
*/
struct Planet struct Planet
{ {
//! Initial position in degrees //! Initial position in degrees
@ -63,6 +67,15 @@ struct Planet
} }
}; };
/**
* \class CPlanet
* \brief Planet manager
*
* Draws the planets orbiting in the sky.
*
* Planets are drawn in 2D mode, at coordinates calculated from camera position.
*/
class CPlanet class CPlanet
{ {
public: public:

View File

@ -90,7 +90,12 @@ struct PyroLightOper
}; };
/**
* \class CPyro
* \brief Fire effect renderer
*
* Functions are only stubs for now.
*/
class CPyro class CPyro
{ {
public: public:

View File

@ -34,19 +34,31 @@ class CEngine;
class CWater; class CWater;
//! Limit of slope considered a flat piece of land
const short FLATLIMIT = (5.0f*Math::PI/180.0f); const short FLATLIMIT = (5.0f*Math::PI/180.0f);
/**
* \enum TerrainRes
* \brief Underground resource type
*/
enum TerrainRes enum TerrainRes
{ {
TR_NULL = 0, //! No resource
TR_STONE = 1, TR_NULL = 0,
TR_URANIUM = 2, //! Titanium
TR_POWER = 3, TR_STONE = 1,
//! Uranium
TR_URANIUM = 2,
//! Energy
TR_POWER = 3,
//! Vault keys
//@{
TR_KEY_A = 4, TR_KEY_A = 4,
TR_KEY_B = 5, TR_KEY_B = 5,
TR_KEY_C = 6, TR_KEY_C = 6,
TR_KEY_D = 7, TR_KEY_D = 7
//@}
}; };
struct BuildingLevel struct BuildingLevel
@ -98,6 +110,10 @@ struct DotLevel
} }
}; };
/**
* \struct FlyingLimit
* \brief Spherical limit of flight
*/
struct FlyingLimit struct FlyingLimit
{ {
Math::Vector center; Math::Vector center;
@ -112,7 +128,22 @@ struct FlyingLimit
}; };
/**
* \class CTerrain
* \brief Terrain loader/generator and manager
*
* Terrain is created from relief textures specifying a XY plane with height
* values which are then scaled and translated into XZ surface forming the
* terrain of game level.
*
* The class also facilitates creating and searching for flat space expanses
* for construction of buildings.
*
* The terrain also specifies underground resources loaded from texture
* and flying limits for the player.
*
* ...
*/
class CTerrain class CTerrain
{ {
public: public:

View File

@ -21,8 +21,10 @@
#include "common/iman.h" #include "common/iman.h"
#include "common/logger.h" #include "common/logger.h"
#include "graphics/core/device.h"
#include "graphics/engine/engine.h" #include "graphics/engine/engine.h"
#include "graphics/engine/terrain.h" #include "graphics/engine/terrain.h"
#include "math/geometry.h"
#include "object/object.h" #include "object/object.h"
#include "sound/sound.h" #include "sound/sound.h"
@ -258,53 +260,41 @@ void Gfx::CWater::AdjustLevel(Math::Vector &pos, Math::Vector &norm,
/** This surface prevents to see the sky (background) underwater! */ /** This surface prevents to see the sky (background) underwater! */
void Gfx::CWater::DrawBack() void Gfx::CWater::DrawBack()
{ {
GetLogger()->Trace("CWater::DrawBack(): stub!\n"); if (! m_draw) return;
/* TODO! if (m_type[0] == WATER_NULL) return;
LPDIRECT3DDEVICE7 device; if (m_lines.empty()) return;
D3DVERTEX2 vertex[4]; // 2 triangles
D3DMATERIAL7 material;
Math::Matrix matrix;
Math::Vector eye, lookat, n, p, p1, p2;
Math::Point uv1, uv2;
float deep, dist;
if ( !m_bDraw ) return; Math::Vector eye = m_engine->GetEyePt();
if ( m_type[0] == WATER_NULL ) return; Math::Vector lookat = m_engine->GetLookatPt();
if ( m_lineUsed == 0 ) return;
eye = m_engine->GetEyePt(); Gfx::Material material;
lookat = m_engine->GetLookatPt();
ZeroMemory( &material, sizeof(D3DMATERIAL7) );
material.diffuse = m_diffuse; material.diffuse = m_diffuse;
material.ambient = m_ambient; material.ambient = m_ambient;
m_engine->SetMaterial(material); m_engine->SetMaterial(material);
m_engine->SetTexture("", 0); m_engine->SetTexture("", 0); // TODO: disable texturing
device = m_engine->GetD3DDevice(); Gfx::CDevice* device = m_engine->GetDevice();
device->SetRenderState(D3DRENDERSTATE_LIGHTING, false);
device->SetRenderState(D3DRENDERSTATE_ZENABLE, false);
device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);
m_engine->SetState(D3DSTATENORMAL);
deep = m_engine->GetDeepView(0); m_engine->SetState(Gfx::ENG_RSTATE_NORMAL);
float deep = m_engine->GetDeepView(0);
m_engine->SetDeepView(deep*2.0f, 0); m_engine->SetDeepView(deep*2.0f, 0);
m_engine->SetFocus(m_engine->GetFocus()); m_engine->SetFocus(m_engine->GetFocus());
m_engine->UpdateMatProj(); // twice the depth of view m_engine->UpdateMatProj(); // twice the depth of view
Math::Matrix matrix;
matrix.LoadIdentity(); matrix.LoadIdentity();
{ device->SetTransform(Gfx::TRANSFORM_WORLD, matrix);
D3DMATRIX mat = MAT_TO_D3DMAT(matrix);
device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
}
Math::Vector p;
p.x = eye.x; p.x = eye.x;
p.z = eye.z; p.z = eye.z;
dist = Math::DistanceProjected(eye, lookat); float dist = Math::DistanceProjected(eye, lookat);
p.x = (lookat.x-eye.x)*deep*1.0f/dist + eye.x; p.x = (lookat.x-eye.x)*deep*1.0f/dist + eye.x;
p.z = (lookat.z-eye.z)*deep*1.0f/dist + eye.z; p.z = (lookat.z-eye.z)*deep*1.0f/dist + eye.z;
Math::Vector p1, p2;
p1.x = (lookat.z-eye.z)*deep*2.0f/dist + p.x; p1.x = (lookat.z-eye.z)*deep*2.0f/dist + p.x;
p1.z = -(lookat.x-eye.x)*deep*2.0f/dist + p.z; p1.z = -(lookat.x-eye.x)*deep*2.0f/dist + p.z;
p2.x = -(lookat.z-eye.z)*deep*2.0f/dist + p.x; p2.x = -(lookat.z-eye.z)*deep*2.0f/dist + p.x;
@ -313,155 +303,132 @@ void Gfx::CWater::DrawBack()
p1.y = -50.0f; p1.y = -50.0f;
p2.y = m_level; p2.y = m_level;
Math::Vector n;
n.x = (lookat.x-eye.x)/dist; n.x = (lookat.x-eye.x)/dist;
n.z = (lookat.z-eye.z)/dist; n.z = (lookat.z-eye.z)/dist;
n.y = 0.0f; n.y = 0.0f;
uv1.x = uv1.y = 0.0f; Gfx::Vertex vertices[4] =
uv2.x = uv2.y = 0.0f; {
Gfx::Vertex(Math::Vector(p1.x, p2.y, p1.z), n),
Gfx::Vertex(Math::Vector(p1.x, p1.y, p1.z), n),
Gfx::Vertex(Math::Vector(p2.x, p2.y, p2.z), n),
Gfx::Vertex(Math::Vector(p2.x, p1.y, p2.z), n)
};
vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p2.y, p1.z), n, uv1.x,uv2.y); device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertices, 4);
vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p1.y, p1.z), n, uv1.x,uv1.y);
vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p2.y, p2.z), n, uv2.x,uv2.y);
vertex[3] = D3DVERTEX2(Math::Vector(p2.x, p1.y, p2.z), n, uv2.x,uv1.y);
device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL);
m_engine->AddStatisticTriangle(2); m_engine->AddStatisticTriangle(2);
m_engine->SetDeepView(deep, 0); m_engine->SetDeepView(deep, 0);
m_engine->SetFocus(m_engine->GetFocus()); m_engine->SetFocus(m_engine->GetFocus());
m_engine->UpdateMatProj(); // gives the initial depth of view m_engine->UpdateMatProj(); // gives the initial depth of view
device->SetRenderState(D3DRENDERSTATE_LIGHTING, true);
device->SetRenderState(D3DRENDERSTATE_ZENABLE, true);
device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);*/
} }
void Gfx::CWater::DrawSurf() void Gfx::CWater::DrawSurf()
{ {
GetLogger()->Trace("CWater::DrawSurf(): stub!\n");
/* TODO!
LPDIRECT3DDEVICE7 device;
D3DVERTEX2* vertex; // triangles
D3DMATERIAL7 material;
Math::Matrix matrix;
Math::Vector eye, lookat, n, pos, p;
Math::Point uv1, uv2;
bool bUnder;
DWORD flags;
float deep, size, sizez, radius;
int rankview, i, j, u;
if (! m_draw) return; if (! m_draw) return;
if (m_type[0] == Gfx::WATER_NULL) return; if (m_type[0] == Gfx::WATER_NULL) return;
if (m_line.empty()) return; if (m_lines.empty()) return;
vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2); std::vector<Gfx::VertexTex2> vertices((m_brick+2)*2, Gfx::VertexTex2());
eye = m_engine->GetEyePt(); Math::Vector eye = m_engine->GetEyePt();
lookat = m_engine->GetLookatPt();
rankview = m_engine->GetRankView(); int rankview = m_engine->GetRankView();
bUnder = ( rankview == 1); bool under = ( rankview == 1);
device = m_engine->GetD3DDevice(); Gfx::CDevice* device = m_engine->GetDevice();
device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);
Math::Matrix matrix;
matrix.LoadIdentity(); matrix.LoadIdentity();
{ device->SetTransform(Gfx::TRANSFORM_WORLD, matrix);
D3DMATRIX mat = MAT_TO_D3DMAT(matrix);
device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
}
ZeroMemory( &material, sizeof(D3DMATERIAL7) ); Gfx::Material material;
material.diffuse = m_diffuse; material.diffuse = m_diffuse;
material.ambient = m_ambient; material.ambient = m_ambient;
m_engine->SetMaterial(material); m_engine->SetMaterial(material);
m_engine->SetTexture(m_filename, 0); m_engine->SetTexture(m_fileName, 0);
m_engine->SetTexture(m_filename, 1); m_engine->SetTexture(m_fileName, 1);
if ( m_type[rankview] == WATER_TT ) if (m_type[rankview] == WATER_TT)
{ m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK | Gfx::ENG_RSTATE_DUAL_WHITE | Gfx::ENG_RSTATE_WRAP, m_color);
m_engine->SetState(D3DSTATETTb|D3DSTATEDUALw|D3DSTATEWRAP, m_color);
}
if ( m_type[rankview] == WATER_TO )
{
m_engine->SetState(D3DSTATENORMAL|D3DSTATEDUALw|D3DSTATEWRAP);
}
if ( m_type[rankview] == WATER_CT )
{
m_engine->SetState(D3DSTATETTb);
}
if ( m_type[rankview] == WATER_CO )
{
m_engine->SetState(D3DSTATENORMAL);
}
device->SetRenderState(D3DRENDERSTATE_FOGENABLE, true);
size = m_size/2.0f; else if (m_type[rankview] == WATER_TO)
if ( bUnder ) sizez = -size; m_engine->SetState(Gfx::ENG_RSTATE_NORMAL | Gfx::ENG_RSTATE_DUAL_WHITE | Gfx::ENG_RSTATE_WRAP);
else sizez = size;
// Draws all the lines. else if (m_type[rankview] == WATER_CT)
deep = m_engine->GetDeepView(0)*1.5f; m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK);
for ( i=0 ; i<m_lineUsed ; i++ ) else if (m_type[rankview] == WATER_CO)
m_engine->SetState(Gfx::ENG_RSTATE_NORMAL);
device->SetRenderState(Gfx::RENDER_STATE_FOG, true);
float size = m_size/2.0f;
float sizez = 0.0f;
if (under) sizez = -size;
else sizez = size;
// Draws all the lines
float deep = m_engine->GetDeepView(0)*1.5f;
for (int i = 0; i < static_cast<int>( m_lines.size() ); i++)
{ {
Math::Vector pos;
pos.y = m_level; pos.y = m_level;
pos.z = m_line[i].pz; pos.z = m_lines[i].pz;
pos.x = m_line[i].px1; pos.x = m_lines[i].px1;
// Visible line? // Visible line?
p = pos; Math::Vector p = pos;
p.x += size*(m_line[i].len-1); p.x += size*(m_lines[i].len-1);
radius = sqrtf(powf(size, 2.0f)+powf(size*m_line[i].len, 2.0f)); float radius = sqrtf(powf(size, 2.0f)+powf(size*m_lines[i].len, 2.0f));
if ( Math::Distance(p, eye) > deep+radius ) continue; if ( Math::Distance(p, eye) > deep+radius ) continue;
D3DVECTOR pD3D = VEC_TO_D3DVEC(p); // TODO: ComputeSphereVisibility
device->ComputeSphereVisibility(&pD3D, &radius, 1, 0, &flags);
if ( flags & D3DSTATUS_CLIPINTERSECTIONALL ) continue; int vertexIndex = 0;
Math::Point uv1, uv2;
Math::Vector n;
u = 0;
p.x = pos.x-size; p.x = pos.x-size;
p.z = pos.z-sizez; p.z = pos.z-sizez;
p.y = pos.y; p.y = pos.y;
AdjustLevel(p, n, uv1, uv2); AdjustLevel(p, n, uv1, uv2);
if ( bUnder ) n.y = -n.y; if (under) n.y = -n.y;
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
p.x = pos.x-size; p.x = pos.x-size;
p.z = pos.z+sizez; p.z = pos.z+sizez;
p.y = pos.y; p.y = pos.y;
AdjustLevel(p, n, uv1, uv2); AdjustLevel(p, n, uv1, uv2);
if ( bUnder ) n.y = -n.y; if (under) n.y = -n.y;
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
for ( j=0 ; j<m_line[i].len ; j++ ) for (int j = 0; j < m_lines[i].len; j++)
{ {
p.x = pos.x+size; p.x = pos.x+size;
p.z = pos.z-sizez; p.z = pos.z-sizez;
p.y = pos.y; p.y = pos.y;
AdjustLevel(p, n, uv1, uv2); AdjustLevel(p, n, uv1, uv2);
if ( bUnder ) n.y = -n.y; if (under) n.y = -n.y;
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
p.x = pos.x+size; p.x = pos.x+size;
p.z = pos.z+sizez; p.z = pos.z+sizez;
p.y = pos.y; p.y = pos.y;
AdjustLevel(p, n, uv1, uv2); AdjustLevel(p, n, uv1, uv2);
if ( bUnder ) n.y = -n.y; if (under) n.y = -n.y;
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
pos.x += size*2.0f; pos.x += size*2.0f;
} }
device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL); device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, &vertices[0], vertexIndex);
m_engine->AddStatisticTriangle(u-2); m_engine->AddStatisticTriangle(vertexIndex - 2);
} }
free(vertex);*/
} }
bool Gfx::CWater::GetWater(int x, int y) bool Gfx::CWater::GetWater(int x, int y)

View File

@ -35,12 +35,19 @@ namespace Gfx {
class CEngine; class CEngine;
class CTerrain; class CTerrain;
/**
* \struct WaterLine
* \brief Water strip
*/
struct WaterLine struct WaterLine
{ {
//! Beginning //@{
//! Beginning of line (terrain coordinates)
short x, y; short x, y;
//! Length by x //@}
//! Length in X direction (terrain coordinates)
short len; short len;
//! X (1, 2) and Z coordinates (world coordinates)
float px1, px2, pz; float px1, px2, pz;
WaterLine() WaterLine()
@ -51,6 +58,10 @@ struct WaterLine
} }
}; };
/**
* \struct WaterVapor
* \brief Water particle effect
*/
struct WaterVapor struct WaterVapor
{ {
bool used; bool used;
@ -68,6 +79,10 @@ struct WaterVapor
} }
}; };
/**
* \enum WaterType
* \brief Mode of water display
*/
enum WaterType enum WaterType
{ {
//! No water //! No water
@ -82,7 +97,19 @@ enum WaterType
WATER_CO = 4, WATER_CO = 4,
}; };
/**
* \class CWater
* \brief Water manager/renderer
*
* Water is drawn where the terrain is below specified level. The mapping
* is based on terrain coordinates - for each "brick" coordinate, the level
* of terrain is tested. For every Y coordinate, many lines in X direction
* are created (WaterLines).
*
* There are two parts of drawing process: drawing the background image
* blocking the normal sky layer and drawing the surface of water.
* The surface is drawn with texture, so with proper texture it can be lava.
*/
class CWater class CWater
{ {
public: public:

View File

@ -20,6 +20,7 @@
#include "common/config.h" #include "common/config.h"
#include "common/image.h" #include "common/image.h"
#include "common/logger.h"
#include "math/geometry.h" #include "math/geometry.h"
@ -80,13 +81,10 @@ void Gfx::CGLDevice::DebugHook()
glColor3i(0, 0, 0); glColor3i(0, 0, 0);
} }
std::string Gfx::CGLDevice::GetError()
{
return m_error;
}
bool Gfx::CGLDevice::Create() bool Gfx::CGLDevice::Create()
{ {
GetLogger()->Info("Creating CDevice\n");
#if defined(USE_GLEW) #if defined(USE_GLEW)
static bool glewInited = false; static bool glewInited = false;
@ -96,13 +94,13 @@ bool Gfx::CGLDevice::Create()
if (glewInit() != GLEW_OK) if (glewInit() != GLEW_OK)
{ {
m_error = "GLEW initialization failed"; GetLogger()->Error("GLEW initialization failed\n");
return false; return false;
} }
if ( (! GLEW_ARB_multitexture) || (! GLEW_EXT_texture_env_combine) || (! GLEW_EXT_secondary_color) ) if ( (! GLEW_ARB_multitexture) || (! GLEW_EXT_texture_env_combine) || (! GLEW_EXT_secondary_color) )
{ {
m_error = "GLEW reports required extensions not supported"; GetLogger()->Error("GLEW reports required extensions not supported\n");
return false; return false;
} }
} }
@ -142,6 +140,8 @@ bool Gfx::CGLDevice::Create()
m_texturesEnabled = std::vector<bool> (maxTextures, false); m_texturesEnabled = std::vector<bool> (maxTextures, false);
m_textureStageParams = std::vector<Gfx::TextureStageParams>(maxTextures, Gfx::TextureStageParams()); m_textureStageParams = std::vector<Gfx::TextureStageParams>(maxTextures, Gfx::TextureStageParams());
GetLogger()->Info("CDevice created successfully\n");
return true; return true;
} }
@ -385,7 +385,7 @@ Gfx::Texture Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCrea
ImageData *data = image->GetData(); ImageData *data = image->GetData();
if (data == NULL) if (data == NULL)
{ {
m_error = "Invalid texture data"; GetLogger()->Error("Invalid texture data\n");
return Gfx::Texture(); // invalid texture return Gfx::Texture(); // invalid texture
} }

View File

@ -78,8 +78,6 @@ public:
virtual void DebugHook(); virtual void DebugHook();
virtual std::string GetError();
virtual bool Create(); virtual bool Create();
virtual void Destroy(); virtual void Destroy();
@ -169,8 +167,6 @@ private:
private: private:
//! Current config //! Current config
Gfx::GLDeviceConfig m_config; Gfx::GLDeviceConfig m_config;
//! Last encountered error
std::string m_error;
//! Current world matrix //! Current world matrix
Math::Matrix m_worldMat; Math::Matrix m_worldMat;

View File

@ -6,7 +6,7 @@ find_package(SDL_image REQUIRED)
find_package(PNG REQUIRED) find_package(PNG REQUIRED)
set(CMAKE_BUILD_TYPE debug) set(CMAKE_BUILD_TYPE debug)
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0") set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0 -Wold-style-cast -std=gnu++0x")
set(ADD_LIBS "") set(ADD_LIBS "")
@ -77,8 +77,9 @@ ${ADD_LIBS}
add_executable(texture_test ${TEXTURE_SOURCES}) add_executable(texture_test ${TEXTURE_SOURCES})
target_link_libraries(texture_test ${LIBS}) target_link_libraries(texture_test ${LIBS})
add_executable(model_test ${MODEL_SOURCES}) # Temporarily disabling because of dependencies on CEngine et al.
target_link_libraries(model_test ${LIBS}) #add_executable(model_test ${MODEL_SOURCES})
#target_link_libraries(model_test ${LIBS})
add_executable(transform_test ${TRANSFORM_SOURCES}) add_executable(transform_test ${TRANSFORM_SOURCES})
target_link_libraries(transform_test ${LIBS}) target_link_libraries(transform_test ${LIBS})

View File

@ -313,7 +313,7 @@ void KeyboardUp(SDLKey key)
void MouseMove(int x, int y) void MouseMove(int x, int y)
{ {
Math::Point currentPos((float)x, (float)y); Math::Point currentPos(static_cast<float>(x), static_cast<float>(y));
static bool first = true; static bool first = true;
if (first || (x < 10) || (y < 10) || (x > 790) || (y > 590)) if (first || (x < 10) || (y < 10) || (x > 790) || (y > 590))
@ -326,8 +326,8 @@ void MouseMove(int x, int y)
return; return;
} }
ROTATION.y = ROTATION_BASE.y + ((float) (x - MOUSE_POS_BASE.x) / 800.0f) * Math::PI; ROTATION.y = ROTATION_BASE.y + (static_cast<float> (x - MOUSE_POS_BASE.x) / 800.0f) * Math::PI;
ROTATION.x = ROTATION_BASE.x + ((float) (y - MOUSE_POS_BASE.y) / 600.0f) * Math::PI; ROTATION.x = ROTATION_BASE.x + (static_cast<float> (y - MOUSE_POS_BASE.y) / 600.0f) * Math::PI;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -378,7 +378,7 @@ int main(int argc, char *argv[])
//SDL_WM_GrabInput(SDL_GRAB_ON); //SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
Gfx::CGLDevice *device = new Gfx::CGLDevice(); Gfx::CGLDevice *device = new Gfx::CGLDevice(Gfx::GLDeviceConfig());
device->Create(); device->Create();
Init(device); Init(device);

View File

@ -54,7 +54,7 @@ void LoadTexture(Gfx::CGLDevice *device, const std::string &name)
Gfx::Texture tex = GetTexture(name); Gfx::Texture tex = GetTexture(name);
if (tex.valid) if (tex.Valid())
return; return;
CImage img; CImage img;
@ -84,7 +84,7 @@ void Init(Gfx::CGLDevice *device, Gfx::CModelFile *model)
{ {
std::vector<Gfx::ModelTriangle> &triangles = model->GetTriangles(); std::vector<Gfx::ModelTriangle> &triangles = model->GetTriangles();
for (int i = 0; i < (int) triangles.size(); ++i) for (int i = 0; i < static_cast<int>( triangles.size() ); ++i)
{ {
LoadTexture(device, triangles[i].tex1Name); LoadTexture(device, triangles[i].tex1Name);
LoadTexture(device, triangles[i].tex2Name); LoadTexture(device, triangles[i].tex2Name);
@ -131,7 +131,7 @@ void Render(Gfx::CGLDevice *device, Gfx::CModelFile *modelFile)
Gfx::VertexTex2 tri[3]; Gfx::VertexTex2 tri[3];
for (int i = 0; i < (int) triangles.size(); ++i) for (int i = 0; i < static_cast<int>( triangles.size() ); ++i)
{ {
device->SetTexture(0, GetTexture(triangles[i].tex1Name)); device->SetTexture(0, GetTexture(triangles[i].tex1Name));
device->SetTexture(1, GetTexture(triangles[i].tex2Name)); device->SetTexture(1, GetTexture(triangles[i].tex2Name));
@ -334,7 +334,7 @@ int main(int argc, char *argv[])
SDL_WM_SetCaption("Model Test", "Model Test"); SDL_WM_SetCaption("Model Test", "Model Test");
Gfx::CGLDevice *device = new Gfx::CGLDevice(); Gfx::CGLDevice *device = new Gfx::CGLDevice(Gfx::GLDeviceConfig());
device->Create(); device->Create();
Init(device, modelFile); Init(device, modelFile);

View File

@ -160,7 +160,7 @@ int main()
SDL_WM_SetCaption("Texture Test", "Texture Test"); SDL_WM_SetCaption("Texture Test", "Texture Test");
Gfx::CGLDevice *device = new Gfx::CGLDevice(); Gfx::CGLDevice *device = new Gfx::CGLDevice(Gfx::GLDeviceConfig());
device->Create(); device->Create();
Init(device); Init(device);

View File

@ -215,7 +215,7 @@ void KeyboardUp(SDLKey key)
void MouseMove(int x, int y) void MouseMove(int x, int y)
{ {
Math::Point currentPos((float)x, (float)y); Math::Point currentPos(static_cast<float>(x), static_cast<float>(y));
static bool first = true; static bool first = true;
if (first || (x < 10) || (y < 10) || (x > 790) || (y > 590)) if (first || (x < 10) || (y < 10) || (x > 790) || (y > 590))
@ -228,8 +228,8 @@ void MouseMove(int x, int y)
return; return;
} }
ROTATION.y = ROTATION_BASE.y + ((float) (x - MOUSE_POS_BASE.x) / 800.0f) * Math::PI; ROTATION.y = ROTATION_BASE.y + (static_cast<float> (x - MOUSE_POS_BASE.x) / 800.0f) * Math::PI;
ROTATION.x = ROTATION_BASE.x + ((float) (y - MOUSE_POS_BASE.y) / 600.0f) * Math::PI; ROTATION.x = ROTATION_BASE.x + (static_cast<float> (y - MOUSE_POS_BASE.y) / 600.0f) * Math::PI;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -280,7 +280,7 @@ int main(int argc, char *argv[])
//SDL_WM_GrabInput(SDL_GRAB_ON); //SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
Gfx::CGLDevice *device = new Gfx::CGLDevice(); Gfx::CGLDevice *device = new Gfx::CGLDevice(Gfx::GLDeviceConfig());
device->Create(); device->Create();
Init(device); Init(device);