summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doxyfile3
-rw-r--r--src/app/README.txt2
-rw-r--r--src/app/app.cpp12
-rw-r--r--src/app/app.h2
-rw-r--r--src/common/README.txt2
-rw-r--r--src/common/event.h2
-rw-r--r--src/common/image.cpp35
-rw-r--r--src/common/image.h6
-rw-r--r--src/common/iman.h2
-rw-r--r--src/graphics/README.txt4
-rw-r--r--src/graphics/core/color.h29
-rw-r--r--src/graphics/core/device.h3
-rw-r--r--src/graphics/core/texture.h34
-rw-r--r--src/graphics/core/vertex.h21
-rw-r--r--src/graphics/d3d/README.txt5
-rw-r--r--src/graphics/engine/README.txt4
-rw-r--r--src/graphics/engine/engine.cpp87
-rw-r--r--src/graphics/engine/engine.h11
-rw-r--r--src/graphics/engine/lightman.cpp147
-rw-r--r--src/graphics/engine/lightman.h58
-rw-r--r--src/graphics/engine/planet.cpp5
-rw-r--r--src/graphics/engine/planet.h3
-rw-r--r--src/graphics/engine/terrain.cpp95
-rw-r--r--src/graphics/engine/text.cpp42
-rw-r--r--src/graphics/engine/text.h5
-rw-r--r--src/graphics/engine/water.cpp23
-rw-r--r--src/graphics/engine/water.h14
-rw-r--r--src/graphics/opengl/README.txt4
-rw-r--r--src/graphics/opengl/gldevice.cpp212
-rw-r--r--src/graphics/opengl/gldevice.h2
-rw-r--r--src/math/README.txt4
-rw-r--r--src/math/geometry.h5
-rw-r--r--src/object/README.txt4
-rw-r--r--src/object/object.cpp16
-rw-r--r--src/object/robotmain.cpp14
-rw-r--r--src/physics/README.txt4
-rw-r--r--src/physics/physics.cpp11
-rw-r--r--src/sound/README.txt4
-rw-r--r--src/ui/README.txt4
39 files changed, 580 insertions, 360 deletions
diff --git a/Doxyfile b/Doxyfile
index cdbf278..8c5fffe 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -700,8 +700,7 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
-EXCLUDE = "src/old" \
- "src/metafile"
+EXCLUDE = "src/CBot/tests"
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
diff --git a/src/app/README.txt b/src/app/README.txt
index e4f69ec..92be8a6 100644
--- a/src/app/README.txt
+++ b/src/app/README.txt
@@ -1,4 +1,4 @@
/**
- * \dir app
+ * \dir src/app
* Main class of the application and system functions
*/
diff --git a/src/app/app.cpp b/src/app/app.cpp
index 8c2dd43..d6fc2dd 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -357,7 +357,7 @@ bool CApplication::Create()
/* SDL initialization sequence */
- Uint32 initFlags = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_TIMER;
+ Uint32 initFlags = SDL_INIT_VIDEO | SDL_INIT_TIMER;
if (SDL_Init(initFlags) < 0)
{
@@ -368,6 +368,12 @@ bool CApplication::Create()
return false;
}
+ // This is non-fatal and besides seems to fix some memory leaks
+ if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
+ {
+ GetLogger()->Warn("Joystick subsystem init failed\nJoystick(s) will not be available\n");
+ }
+
if ((IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) == 0)
{
m_errorMessage = std::string("SDL_Image initialization error:\n") +
@@ -398,10 +404,6 @@ bool CApplication::Create()
SDL_JoystickEventState(SDL_IGNORE);
- // For now, enable joystick for testing
- SetJoystickEnabled(true);
-
-
// The video is ready, we can create and initalize the graphics device
m_device = new Gfx::CGLDevice(m_deviceConfig);
if (! m_device->Create() )
diff --git a/src/app/app.h b/src/app/app.h
index f1e2c7f..e887a63 100644
--- a/src/app/app.h
+++ b/src/app/app.h
@@ -75,7 +75,7 @@ enum VideoQueryResult
/**
- * \enum TrackedKeys
+ * \enum TrackedKey
* \brief Additional keys whose state (pressed/released) is tracked by CApplication
*/
enum TrackedKey
diff --git a/src/common/README.txt b/src/common/README.txt
index 73d65b7..25c9fbf 100644
--- a/src/common/README.txt
+++ b/src/common/README.txt
@@ -1,4 +1,4 @@
/**
- * \dir common
+ * \dir src/common
* \brief Structs and utils shared throughout the application
*/
diff --git a/src/common/event.h b/src/common/event.h
index dc50ee6..ce2872a 100644
--- a/src/common/event.h
+++ b/src/common/event.h
@@ -81,7 +81,7 @@ enum WheelDirection
};
/**
- * \enum MouseWheelEventData
+ * \struct MouseWheelEventData
* \brief Additional data for mouse wheel event.
*/
struct MouseWheelEventData
diff --git a/src/common/image.cpp b/src/common/image.cpp
index 50f6eee..6a2ab0e 100644
--- a/src/common/image.cpp
+++ b/src/common/image.cpp
@@ -190,7 +190,7 @@ Math::IntPoint CImage::GetSize() const
* \param pixel pixel coords (range x: 0..width-1 y: 0..height-1)
* \returns color
*/
-Gfx::Color CImage::GetPixel(Math::IntPoint pixel)
+Gfx::IntColor CImage::GetPixelInt(Math::IntPoint pixel)
{
assert(m_data != nullptr);
assert(pixel.x >= 0 || pixel.x <= m_data->surface->w);
@@ -229,16 +229,28 @@ Gfx::Color CImage::GetPixel(Math::IntPoint pixel)
Uint8 r = 0, g = 0, b = 0, a = 0;
SDL_GetRGBA(u, m_data->surface->format, &r, &g, &b, &a);
- return Gfx::Color(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
+ return Gfx::IntColor(r, g, b, a);
+}
+
+/**
+ * Image must be valid and pixel coords in valid range.
+ *
+ * \param pixel pixel coords (range x: 0..width-1 y: 0..height-1)
+ * \returns color
+ */
+Gfx::Color CImage::GetPixel(Math::IntPoint pixel)
+{
+ return Gfx::IntColorToColor(GetPixelInt(pixel));
}
+
/**
* Image must be valid and pixel coords in valid range.
*
* \param pixel pixel coords (range x: 0..width-1 y: 0..height-1)
* \param color color
*/
-void CImage::SetPixel(Math::IntPoint pixel, Gfx::Color color)
+void CImage::SetPixelInt(Math::IntPoint pixel, Gfx::IntColor color)
{
assert(m_data != nullptr);
assert(pixel.x >= 0 || pixel.x <= m_data->surface->w);
@@ -248,11 +260,7 @@ void CImage::SetPixel(Math::IntPoint pixel, Gfx::Color color)
int index = pixel.y * m_data->surface->pitch + pixel.x * bpp;
Uint8* p = &static_cast<Uint8*>(m_data->surface->pixels)[index];
- Uint8 r = static_cast<Uint8>(color.r * 255.0f);
- Uint8 g = static_cast<Uint8>(color.g * 255.0f);
- Uint8 b = static_cast<Uint8>(color.b * 255.0f);
- Uint8 a = static_cast<Uint8>(color.a * 255.0f);
- Uint32 u = SDL_MapRGBA(m_data->surface->format, r, g, b, a);
+ Uint32 u = SDL_MapRGBA(m_data->surface->format, color.r, color.g, color.b, color.a);
switch(bpp)
{
@@ -288,6 +296,17 @@ void CImage::SetPixel(Math::IntPoint pixel, Gfx::Color color)
}
}
+/**
+ * Image must be valid and pixel coords in valid range.
+ *
+ * \param pixel pixel coords (range x: 0..width-1 y: 0..height-1)
+ * \param color color
+ */
+void CImage::SetPixel(Math::IntPoint pixel, Gfx::Color color)
+{
+ SetPixelInt(pixel, Gfx::ColorToIntColor(color));
+}
+
std::string CImage::GetError()
{
return m_error;
diff --git a/src/common/image.h b/src/common/image.h
index 93c7cab..3391bdb 100644
--- a/src/common/image.h
+++ b/src/common/image.h
@@ -78,9 +78,15 @@ public:
//! Sets the color at given pixel
void SetPixel(Math::IntPoint pixel, Gfx::Color color);
+ //! Sets the precise color at given pixel
+ void SetPixelInt(Math::IntPoint pixel, Gfx::IntColor color);
+
//! Returns the color at given pixel
Gfx::Color GetPixel(Math::IntPoint pixel);
+ //! Returns the precise color at given pixel
+ Gfx::IntColor GetPixelInt(Math::IntPoint pixel);
+
//! Loads an image from the specified file
bool Load(const std::string &fileName);
diff --git a/src/common/iman.h b/src/common/iman.h
index 44f143a..75655aa 100644
--- a/src/common/iman.h
+++ b/src/common/iman.h
@@ -95,7 +95,7 @@ enum ManagedClassType
/**
- * \enum ManagedClassInstances
+ * \struct ManagedClassInstances
* \brief Instances of class managed by CInstanceManager
*/
struct ManagedClassInstances
diff --git a/src/graphics/README.txt b/src/graphics/README.txt
index 479747b..1cb91ba 100644
--- a/src/graphics/README.txt
+++ b/src/graphics/README.txt
@@ -1,5 +1,5 @@
/**
- * \dir graphics
+ * \dir src/graphics
* \brief Graphics engine
*/
@@ -9,4 +9,4 @@
*
* This namespace was created to avoid clashing with old code, but now it still serves,
* defining a border between pure graphics engine and other parts of application.
- */ \ No newline at end of file
+ */
diff --git a/src/graphics/core/color.h b/src/graphics/core/color.h
index 4b152c1..0bec7e9 100644
--- a/src/graphics/core/color.h
+++ b/src/graphics/core/color.h
@@ -79,6 +79,35 @@ struct Color
};
/**
+ * \struct IntColor
+ * \brief Color with integer values
+ *
+ * May be used for precise pixel manipulations.
+ */
+struct IntColor
+{
+ //! Red, green, blue and alpha components
+ unsigned char r, g, b, a;
+
+ //! Constructor; default values are (0,0,0,0) = black
+ explicit IntColor(unsigned char aR = 0, unsigned char aG = 0, unsigned char aB = 0, unsigned char aA = 0)
+ : r(aR), g(aG), b(aB), a(aA) {}
+};
+
+inline Color IntColorToColor(IntColor color)
+{
+ return Color(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f);
+}
+
+inline IntColor ColorToIntColor(Color color)
+{
+ return IntColor(static_cast<unsigned char>(color.r * 255.0f),
+ static_cast<unsigned char>(color.g * 255.0f),
+ static_cast<unsigned char>(color.b * 255.0f),
+ static_cast<unsigned char>(color.a * 255.0f));
+}
+
+/**
* \struct ColorHSV
* \brief HSV color
*/
diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h
index 7c60d21..71ebef7 100644
--- a/src/graphics/core/device.h
+++ b/src/graphics/core/device.h
@@ -305,6 +305,9 @@ public:
//! Returns the current params of texture stage with given index
virtual TextureStageParams GetTextureStageParams(int index) = 0;
+ //! Sets only the texture wrap modes (for faster than thru stage params)
+ virtual void SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wrapT) = 0;
+
//! Sets the texture factor to the given color value
virtual void SetTextureFactor(const Color &color) = 0;
//! Returns the current texture factor
diff --git a/src/graphics/core/texture.h b/src/graphics/core/texture.h
index e9117e2..3ebbee5 100644
--- a/src/graphics/core/texture.h
+++ b/src/graphics/core/texture.h
@@ -28,6 +28,7 @@
// Graphics module namespace
namespace Gfx {
+
/**
* \enum TexImgFormat
* \brief Format of image data
@@ -117,11 +118,12 @@ enum TexMixArgument
};
/**
- \struct TextureCreateParams
- \brief Parameters for texture creation
-
- These params define how particular texture is created and later displayed.
- They must be specified at texture creation time and cannot be changed later. */
+ * \struct TextureCreateParams
+ * \brief Parameters for texture creation
+ *
+ * These params define how particular texture is created and later displayed.
+ * They must be specified at texture creation time and cannot be changed later.
+ */
struct TextureCreateParams
{
//! Whether to generate mipmaps
@@ -149,11 +151,12 @@ struct TextureCreateParams
};
/**
- \struct TextureStageParams
- \brief Parameters for a texture unit
-
- These params define the behavior of texturing units (stages).
- They can be changed freely and are feature of graphics engine, not any particular texture. */
+ * \struct TextureStageParams
+ * \brief Parameters for a texture unit
+ *
+ * These params define the behavior of texturing units (stages).
+ * They can be changed freely and are features of graphics engine, not any particular texture.
+ */
struct TextureStageParams
{
//! Mixing operation done on color values
@@ -193,11 +196,12 @@ struct TextureStageParams
};
/**
- \struct Texture
- \brief Info about a texture
-
- Identifies (through id) a texture created in graphics engine.
- Also contains some additional data. */
+ * \struct Texture
+ * \brief Info about a texture
+ *
+ * Identifies (through id) a texture created in graphics engine.
+ * Also contains some additional data.
+ */
struct Texture
{
//! ID of the texture in graphics engine; 0 = invalid texture
diff --git a/src/graphics/core/vertex.h b/src/graphics/core/vertex.h
index e2c35c3..fa6120f 100644
--- a/src/graphics/core/vertex.h
+++ b/src/graphics/core/vertex.h
@@ -33,6 +33,7 @@
// Graphics module namespace
namespace Gfx {
+
/**
* \struct Vertex
* \brief Vertex of a primitive
@@ -43,17 +44,23 @@ namespace Gfx {
* - vertex coordinates (x,y,z) as Math::Vector,
* - normal coordinates (nx,ny,nz) as Math::Vector
* - texture coordinates (u,v) as Math::Point.
+ *
+ * Additional padding is provided to align to even multiplies of 4 floats for faster access.
*/
struct Vertex
{
Math::Vector coord;
+ float pad1;
Math::Vector normal;
+ float pad2;
Math::Point texCoord;
+ float pad3, pad4;
explicit Vertex(Math::Vector aCoord = Math::Vector(),
Math::Vector aNormal = Math::Vector(),
Math::Point aTexCoord = Math::Point())
- : coord(aCoord), normal(aNormal), texCoord(aTexCoord) {}
+ : coord(aCoord), pad1(0.0f), normal(aNormal),
+ pad2(0.0f),texCoord(aTexCoord), pad3(0.0f), pad4(0.0f) {}
//! Returns a string "(c: [...], n: [...], tc: [...])"
@@ -74,16 +81,19 @@ struct Vertex
* It contains:
* - vertex coordinates (x,y,z) as Math::Vector,
* - RGBA color as Color
+ *
+ * Additional padding is provided to align to even multiplies of 4 floats for faster access.
*/
struct VertexCol
{
Math::Vector coord;
+ float pad;
Color color;
explicit VertexCol(Math::Vector aCoord = Math::Vector(),
Color aColor = Color(),
Math::Point aTexCoord = Math::Point())
- : coord(aCoord), color(aColor) {}
+ : coord(aCoord), pad(0.0f), color(aColor) {}
//! Returns a string "(c: [...], col: [...])"
inline std::string ToString() const
@@ -102,11 +112,15 @@ struct VertexCol
*
* In addition to fields from Vector, it contains
* secondary texture coordinates (u2, v2) as Math::Point
+ *
+ * Additional padding is provided to align to even multiplies of 4 floats for faster access.
*/
struct VertexTex2
{
Math::Vector coord;
+ float pad1;
Math::Vector normal;
+ float pad2;
Math::Point texCoord;
Math::Point texCoord2;
@@ -114,7 +128,8 @@ struct VertexTex2
Math::Vector aNormal = Math::Vector(),
Math::Point aTexCoord = Math::Point(),
Math::Point aTexCoord2 = Math::Point())
- : coord(aCoord), normal(aNormal), texCoord(aTexCoord), texCoord2(aTexCoord2) {}
+ : coord(aCoord), pad1(0.0f), normal(aNormal), pad2(0.0f),
+ texCoord(aTexCoord), texCoord2(aTexCoord2) {}
//! Sets the fields from Vertex with texCoord2 = (0,0)
void FromVertex(const Vertex &v)
diff --git a/src/graphics/d3d/README.txt b/src/graphics/d3d/README.txt
index 524ae7b..0fe7db6 100644
--- a/src/graphics/d3d/README.txt
+++ b/src/graphics/d3d/README.txt
@@ -1,4 +1 @@
-/**
- * \dir graphics/d3d
- * \brief Possible future DirectX implementation of graphics engine
- */ \ No newline at end of file
+Possible future DirectX implementation of graphics engine
diff --git a/src/graphics/engine/README.txt b/src/graphics/engine/README.txt
index f64d3dd..05d2d76 100644
--- a/src/graphics/engine/README.txt
+++ b/src/graphics/engine/README.txt
@@ -1,9 +1,9 @@
/**
- * \dir graphics/engine
+ * \dir src/graphics/engine
* \brief Graphics engine
*
* CEngine class and various other classes implementing the main features
* of graphics engine from model loading to decorative particles
*
* Graphics operations are done on abstract interface from src/graphics/core
- */ \ No newline at end of file
+ */
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index c170922..e34034d 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -186,6 +186,8 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
m_updateGeometry = false;
+ m_interfaceMode = false;
+
m_mice[ENG_MOUSE_NORM] = EngineMouse( 0, 1, 32, ENG_RSTATE_TTEXTURE_WHITE, ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 1.0f, 1.0f));
m_mice[ENG_MOUSE_WAIT] = EngineMouse( 2, 3, 33, ENG_RSTATE_TTEXTURE_WHITE, ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 8.0f, 12.0f));
m_mice[ENG_MOUSE_HAND] = EngineMouse( 4, 5, 34, ENG_RSTATE_TTEXTURE_WHITE, ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 7.0f, 2.0f));
@@ -215,6 +217,11 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
m_defaultTexParams.minFilter = TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR;
m_defaultTexParams.magFilter = TEX_MAG_FILTER_LINEAR;
+ m_terrainTexParams.format = TEX_IMG_AUTO;
+ m_terrainTexParams.mipmap = false;
+ m_terrainTexParams.minFilter = TEX_MIN_FILTER_LINEAR;
+ m_terrainTexParams.magFilter = TEX_MAG_FILTER_LINEAR;
+
m_objectTree.reserve(LEVEL1_PREALLOCATE_COUNT);
m_objects.reserve(OBJECT_PREALLOCATE_COUNT);
m_shadows.reserve(SHADOW_PREALLOCATE_COUNT);
@@ -1947,13 +1954,8 @@ void CEngine::SetState(int state, const Color& color)
m_device->SetBlendFunc(BLEND_SRC_ALPHA, BLEND_INV_SRC_ALPHA);
m_device->SetRenderState(RENDER_STATE_TEXTURING, true);
-
- TextureStageParams params;
- params.colorOperation = TEX_MIX_OPER_DEFAULT; // default modulate operation
- params.alphaOperation = TEX_MIX_OPER_DEFAULT; // default modulate operation
-
m_device->SetTextureEnabled(0, true);
- m_device->SetTextureStageParams(0, params);
+ m_device->SetTextureStageParams(0, TextureStageParams()); // default operation
}
else if (state & ENG_RSTATE_ALPHA) // image with alpha channel?
{
@@ -2014,7 +2016,7 @@ void CEngine::SetState(int state, const Color& color)
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
params.colorArg2 = TEX_MIX_ARG_COMPUTED_COLOR;
params.alphaOperation = TEX_MIX_OPER_DEFAULT; // TODO: ???
- m_device->SetTextureEnabled(0, true);
+ m_device->SetTextureEnabled(1, true);
m_device->SetTextureStageParams(1, params);
}
else if ((state & ENG_RSTATE_DUAL_WHITE) && second)
@@ -2024,7 +2026,7 @@ void CEngine::SetState(int state, const Color& color)
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
params.colorArg2 = TEX_MIX_ARG_COMPUTED_COLOR;
params.alphaOperation = TEX_MIX_OPER_DEFAULT; // TODO: ???
- m_device->SetTextureEnabled(0, true);
+ m_device->SetTextureEnabled(1, true);
m_device->SetTextureStageParams(1, params);
}
else
@@ -2034,25 +2036,13 @@ void CEngine::SetState(int state, const Color& color)
if (state & ENG_RSTATE_WRAP)
{
- // TODO: separate function for setting wrap mode?
-
- TextureStageParams p1 = m_device->GetTextureStageParams(0);
- p1.wrapS = p1.wrapT = TEX_WRAP_REPEAT;
- m_device->SetTextureStageParams(0, p1);
-
- TextureStageParams p2 = m_device->GetTextureStageParams(1);
- p2.wrapS = p2.wrapT = TEX_WRAP_REPEAT;
- m_device->SetTextureStageParams(1, p2);
+ m_device->SetTextureStageWrap(0, TEX_WRAP_REPEAT, TEX_WRAP_REPEAT);
+ m_device->SetTextureStageWrap(1, TEX_WRAP_REPEAT, TEX_WRAP_REPEAT);
}
else // if (state & ENG_RSTATE_CLAMP) or otherwise
{
- TextureStageParams p1 = m_device->GetTextureStageParams(0);
- p1.wrapS = p1.wrapT = TEX_WRAP_CLAMP;
- m_device->SetTextureStageParams(0, p1);
-
- TextureStageParams p2 = m_device->GetTextureStageParams(1);
- p2.wrapS = p2.wrapT = TEX_WRAP_CLAMP;
- m_device->SetTextureStageParams(1, p2);
+ m_device->SetTextureStageWrap(0, TEX_WRAP_CLAMP, TEX_WRAP_CLAMP);
+ m_device->SetTextureStageWrap(1, TEX_WRAP_CLAMP, TEX_WRAP_CLAMP);
}
if (state & ENG_RSTATE_2FACE)
@@ -2069,6 +2059,13 @@ void CEngine::SetState(int state, const Color& color)
m_device->SetGlobalAmbient(Color(1.0f, 1.0f, 1.0f, 1.0f));
else
m_device->SetGlobalAmbient(m_ambientColor[m_rankView]);
+
+
+ // In interface mode, disable lighting
+ if (m_interfaceMode)
+ {
+ m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
+ }
}
void CEngine::SetMaterial(const Material& mat)
@@ -2177,16 +2174,35 @@ bool CEngine::LoadAllTextures()
EngineObjLevel1& p1 = m_objectTree[l1];
if (! p1.used) continue;
+ bool terrain = false;
+
+ for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
+ {
+ EngineObjLevel2& p2 = p1.next[l2];
+ if (! p2.used) continue;
+
+ if (m_objects[p2.objRank].type == ENG_OBJTYPE_TERRAIN)
+ terrain = true;
+ }
+
if (! p1.tex1Name.empty())
{
- p1.tex1 = LoadTexture(p1.tex1Name);
+ if (terrain)
+ p1.tex1 = LoadTexture(p1.tex1Name, m_terrainTexParams);
+ else
+ p1.tex1 = LoadTexture(p1.tex1Name);
+
if (! p1.tex1.Valid())
ok = false;
}
if (! p1.tex2Name.empty())
{
- p1.tex2 = LoadTexture(p1.tex2Name);
+ if (terrain)
+ p1.tex2 = LoadTexture(p1.tex2Name, m_terrainTexParams);
+ else
+ p1.tex2 = LoadTexture(p1.tex2Name);
+
if (! p1.tex2.Valid())
ok = false;
}
@@ -2810,7 +2826,7 @@ void CEngine::Draw3DScene()
if (m_shadowVisible)
{
- m_lightMan->UpdateLightsEnableState(ENG_OBJTYPE_TERRAIN);
+ m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN);
// Draw the terrain
@@ -2910,7 +2926,7 @@ void CEngine::Draw3DScene()
if (! IsVisible(objRank))
continue;
- m_lightMan->UpdateLightsEnableState(m_objects[objRank].type);
+ m_lightMan->UpdateDeviceLights(m_objects[objRank].type);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
@@ -2999,7 +3015,7 @@ void CEngine::Draw3DScene()
if (! IsVisible(objRank))
continue;
- m_lightMan->UpdateLightsEnableState(m_objects[objRank].type);
+ m_lightMan->UpdateDeviceLights(m_objects[objRank].type);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
@@ -3041,7 +3057,7 @@ void CEngine::Draw3DScene()
}
}
- m_lightMan->UpdateLightsEnableState(ENG_OBJTYPE_TERRAIN);
+ m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN);
if (m_waterMode) m_water->DrawSurf(); // draws water surface
@@ -3064,11 +3080,20 @@ void CEngine::DrawInterface()
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
+ // Force new state to disable lighting
+ m_interfaceMode = true;
+ m_lastState = -1;
+ SetState(Gfx::ENG_RSTATE_NORMAL);
+
// Draw the entire interface
Ui::CInterface* interface = static_cast<Ui::CInterface*>( m_iMan->SearchInstance(CLASS_INTERFACE) );
if (interface != nullptr)
interface->Draw();
+ m_interfaceMode = false;
+ m_lastState = -1;
+ SetState(Gfx::ENG_RSTATE_NORMAL);
+
m_particle->DrawParticle(SH_INTERFACE); // draws the particles of the interface
// 3D objects drawn in front of interface
@@ -3117,7 +3142,7 @@ void CEngine::DrawInterface()
if (! IsVisible(objRank))
continue;
- m_lightMan->UpdateLightsEnableState(m_objects[objRank].type);
+ m_lightMan->UpdateDeviceLights(m_objects[objRank].type);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h
index e36865c..6363fd3 100644
--- a/src/graphics/engine/engine.h
+++ b/src/graphics/engine/engine.h
@@ -568,7 +568,7 @@ struct EngineMouse
*
* It uses a lower-level CDevice object which is implementation-independent core engine.
*
- * \section 3DScene 3D Scene
+ * \section Scene 3D Scene
*
* The 3D scene is drawn with view coordinates set from camera position in 3D space and
* a perspective projection matrix. The world matrix depends on the object drawn.
@@ -588,7 +588,7 @@ struct EngineMouse
* - mouse cursor
* - animated highlight box of the selected object(s)
*
- * \section 2DInterface 2D Interface
+ * \section Interface 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).
@@ -601,7 +601,7 @@ struct EngineMouse
* are instances of CControl class. The source code for these classes is in
* src/ui directory.
*
- * \section Objecs Engine Objects
+ * \section Objects Engine Objects
*
* The 3D scene is composed of objects which are basically collections of triangles forming
* a surface or simply independent triangles in space.
@@ -1348,6 +1348,8 @@ protected:
//! Default texture create params
TextureCreateParams m_defaultTexParams;
+ //! Create params for terrain textures
+ TextureCreateParams m_terrainTexParams;
//! Map of loaded textures (by name)
std::map<std::string, Texture> m_texNameMap;
@@ -1375,6 +1377,9 @@ protected:
std::string m_lastTexture[2];
//! Last material
Material m_lastMaterial;
+
+ //! True when drawing 2D UI
+ bool m_interfaceMode;
};
diff --git a/src/graphics/engine/lightman.cpp b/src/graphics/engine/lightman.cpp
index 02719de..3055f08 100644
--- a/src/graphics/engine/lightman.cpp
+++ b/src/graphics/engine/lightman.cpp
@@ -18,6 +18,7 @@
#include "graphics/engine/lightman.h"
+#include "common/logger.h"
#include "common/iman.h"
#include "graphics/core/device.h"
@@ -28,6 +29,7 @@
#include <cmath>
+// Graphics module namespace
namespace Gfx {
@@ -70,6 +72,7 @@ void LightProgression::SetTarget(float value)
DynamicLight::DynamicLight()
{
used = enabled = false;
+ priority = LIGHT_PRI_LOW;
includeType = excludeType = ENG_OBJTYPE_NULL;
}
@@ -80,7 +83,7 @@ CLightManager::CLightManager(CInstanceManager* iMan, CEngine* engine)
m_iMan = iMan;
m_iMan->AddInstance(CLASS_LIGHT, this);
- m_device = NULL;
+ m_device = nullptr;
m_engine = engine;
m_time = 0.0f;
@@ -90,56 +93,54 @@ CLightManager::~CLightManager()
{
m_iMan->DeleteInstance(CLASS_LIGHT, this);
- m_iMan = NULL;
- m_device = NULL;
- m_engine = NULL;
+ m_iMan = nullptr;
+ m_device = nullptr;
+ m_engine = nullptr;
}
void CLightManager::SetDevice(CDevice* device)
{
m_device = device;
-
- m_dynLights = std::vector<DynamicLight>(m_device->GetMaxLightCount(), DynamicLight());
+ m_lightMap = std::vector<int>(m_device->GetMaxLightCount(), -1);
}
void CLightManager::FlushLights()
{
- for (int i = 0; i < static_cast<int>( m_dynLights.size() ); i++)
- {
- m_dynLights[i].used = false;
- m_device->SetLightEnabled(i, false);
- }
+ m_dynLights.clear();
}
-/** Returns the index of light created or -1 if all lights are used. */
-int CLightManager::CreateLight()
+/** Returns the index of light created. */
+int CLightManager::CreateLight(LightPriority priority)
{
- for (int i = 0; i < static_cast<int>( m_dynLights.size() ); i++)
+ int index = 0;
+ for (; index < static_cast<int>( m_dynLights.size() ); index++)
{
- if (m_dynLights[i].used) continue;
-
- m_dynLights[i] = DynamicLight();
+ if (! m_dynLights[index].used)
+ break;
+ }
- m_dynLights[i].used = true;
- m_dynLights[i].enabled = true;
+ if (index == static_cast<int>(m_dynLights.size()))
+ m_dynLights.push_back(DynamicLight());
- m_dynLights[i].includeType = ENG_OBJTYPE_NULL;
- m_dynLights[i].excludeType = ENG_OBJTYPE_NULL;
+ m_dynLights[index] = DynamicLight();
+ m_dynLights[index].used = true;
+ m_dynLights[index].enabled = true;
+ m_dynLights[index].priority = priority;
- m_dynLights[i].light.type = LIGHT_DIRECTIONAL;
- m_dynLights[i].light.diffuse = Color(0.5f, 0.5f, 0.5f);
- m_dynLights[i].light.position = Math::Vector(-100.0f, 100.0f, -100.0f);
- m_dynLights[i].light.direction = Math::Vector( 1.0f, -1.0f, 1.0f);
+ m_dynLights[index].includeType = ENG_OBJTYPE_NULL;
+ m_dynLights[index].excludeType = ENG_OBJTYPE_NULL;
- m_dynLights[i].intensity.Init(1.0f); // maximum
- m_dynLights[i].colorRed.Init(0.5f);
- m_dynLights[i].colorGreen.Init(0.5f);
- m_dynLights[i].colorBlue.Init(0.5f); // gray
+ m_dynLights[index].light.type = LIGHT_DIRECTIONAL;
+ m_dynLights[index].light.diffuse = Color(0.5f, 0.5f, 0.5f);
+ m_dynLights[index].light.position = Math::Vector(-100.0f, 100.0f, -100.0f);
+ m_dynLights[index].light.direction = Math::Vector( 1.0f, -1.0f, 1.0f);
- return i;
- }
+ m_dynLights[index].intensity.Init(1.0f); // maximum
+ m_dynLights[index].colorRed.Init(0.5f);
+ m_dynLights[index].colorGreen.Init(0.5f);
+ m_dynLights[index].colorBlue.Init(0.5f); // gray
- return -1;
+ return index;
}
bool CLightManager::DeleteLight(int lightRank)
@@ -148,8 +149,6 @@ bool CLightManager::DeleteLight(int lightRank)
return false;
m_dynLights[lightRank].used = false;
- m_device->SetLightEnabled(lightRank, false);
-
return true;
}
@@ -357,7 +356,6 @@ void CLightManager::UpdateProgression(float rTime)
}
}
-
void CLightManager::UpdateLights()
{
for (int i = 0; i < static_cast<int>( m_dynLights.size() ); i++)
@@ -366,7 +364,8 @@ void CLightManager::UpdateLights()
continue;
bool enabled = m_dynLights[i].enabled;
- if (m_dynLights[i].intensity.current == 0.0f)
+
+ if (Math::IsZero(m_dynLights[i].intensity.current))
enabled = false;
if (enabled)
@@ -379,42 +378,96 @@ void CLightManager::UpdateLights()
value = m_dynLights[i].colorBlue.current * m_dynLights[i].intensity.current;
m_dynLights[i].light.diffuse.b = value;
-
- m_device->SetLight(i, m_dynLights[i].light);
- m_device->SetLightEnabled(i, enabled);
}
else
{
m_dynLights[i].light.diffuse.r = 0.0f;
m_dynLights[i].light.diffuse.g = 0.0f;
m_dynLights[i].light.diffuse.b = 0.0f;
-
- m_device->SetLightEnabled(i, enabled);
}
}
}
-void CLightManager::UpdateLightsEnableState(EngineObjectType type)
+void CLightManager::UpdateDeviceLights(EngineObjectType type)
{
+ for (int i = 0; i < static_cast<int>( m_lightMap.size() ); ++i)
+ m_lightMap[i] = -1;
+
+ // High priority
for (int i = 0; i < static_cast<int>( m_dynLights.size() ); i++)
{
if (! m_dynLights[i].used)
continue;
if (! m_dynLights[i].enabled)
continue;
- if (m_dynLights[i].intensity.current == 0.0f)
+ if (Math::IsZero(m_dynLights[i].intensity.current))
+ continue;
+ if (m_dynLights[i].priority == LIGHT_PRI_LOW)
continue;
+ bool enabled = true;
if (m_dynLights[i].includeType != ENG_OBJTYPE_NULL)
+ enabled = (m_dynLights[i].includeType == type);
+
+ if (m_dynLights[i].excludeType != ENG_OBJTYPE_NULL)
+ enabled = (m_dynLights[i].excludeType != type);
+
+ if (enabled)
{
- bool enabled = (m_dynLights[i].includeType == type);
- m_device->SetLightEnabled(i, enabled);
+ for (int j = 0; j < static_cast<int>( m_lightMap.size() ); ++j)
+ {
+ if (m_lightMap[j] == -1)
+ {
+ m_lightMap[j] = i;
+ break;
+ }
+ }
}
+ }
+
+ // Low priority
+ for (int i = 0; i < static_cast<int>( m_dynLights.size() ); i++)
+ {
+ if (! m_dynLights[i].used)
+ continue;
+ if (! m_dynLights[i].enabled)
+ continue;
+ if (m_dynLights[i].intensity.current == 0.0f)
+ continue;
+ if (m_dynLights[i].priority == LIGHT_PRI_HIGH)
+ continue;
+
+ bool enabled = true;
+ if (m_dynLights[i].includeType != ENG_OBJTYPE_NULL)
+ enabled = (m_dynLights[i].includeType == type);
if (m_dynLights[i].excludeType != ENG_OBJTYPE_NULL)
+ enabled = (m_dynLights[i].excludeType != type);
+
+ if (enabled)
+ {
+ for (int j = 0; j < static_cast<int>( m_lightMap.size() ); ++j)
+ {
+ if (m_lightMap[j] == -1)
+ {
+ m_lightMap[j] = i;
+ break;
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < static_cast<int>( m_lightMap.size() ); ++i)
+ {
+ int rank = m_lightMap[i];
+ if (rank != -1)
+ {
+ m_device->SetLight(i, m_dynLights[rank].light);
+ m_device->SetLightEnabled(i, true);
+ }
+ else
{
- bool enabled = (m_dynLights[i].excludeType != type);
- m_device->SetLightEnabled(i, enabled);
+ m_device->SetLightEnabled(i, false);
}
}
}
diff --git a/src/graphics/engine/lightman.h b/src/graphics/engine/lightman.h
index c50d176..d83dfb3 100644
--- a/src/graphics/engine/lightman.h
+++ b/src/graphics/engine/lightman.h
@@ -34,8 +34,9 @@
namespace Gfx {
/**
- \struct LightProgression
- \brief Describes the progression of light parameters change */
+ * \struct LightProgression
+ * \brief Describes the progression of light parameters change
+ */
struct LightProgression
{
//! Starting value
@@ -65,11 +66,22 @@ struct LightProgression
};
/**
- \struct DynamicLight
- \brief Dynamic light in 3D scene
+ * \enum LightPriority
+ * \brief Priority in light assignment
+ */
+enum LightPriority
+{
+ LIGHT_PRI_HIGH,
+ LIGHT_PRI_LOW
+};
- It is an extension over standard light properties. Added are dynamic progressions for light
- colors and intensity and types of objects included/excluded in lighting. */
+/**
+ * \struct DynamicLight
+ * \brief Dynamic light in 3D scene
+ *
+ * It is an extension over standard light properties. Added are dynamic progressions for light
+ * colors and intensity and types of objects included/excluded in lighting.
+ */
struct DynamicLight
{
//! Whether the light is used
@@ -77,6 +89,9 @@ struct DynamicLight
//! Whether the light is turned on
bool enabled;
+ //! Priority in assignment
+ LightPriority priority;
+
//! Configuration of the light
Light light;
@@ -98,17 +113,18 @@ struct DynamicLight
};
/**
- \class CLightManager
- \brief Manager for dynamic lights in 3D scene
-
- (Old CLight class)
-
- The class is responsible for managing dynamic lights (struct DynamicLight) used in 3D scene.
- The dynamic lights are created, updated and deleted through the class' interface.
-
- Number of available lights depends on graphics device used. Class allocates vector
- for the total number of lights, but only some are used.
- */
+ * \class CLightManager
+ * \brief Manager for dynamic lights in 3D scene
+ *
+ * The class is responsible for managing dynamic lights (struct DynamicLight) used in 3D scene.
+ * The dynamic lights are created, updated and deleted through the class' interface.
+ *
+ * Since there is a limit on total number of lights available in OpenGL (usually up to 8), the dynamic lights
+ * must be emulated by displaying only some of them. All functions normally operate only on DynamicLight structs,
+ * updating the models with new values, while only one function, UpdateDeviceLights(), performs the actual
+ * synchronization to the device. It allocates device's light slots as necessary, with two priority levels
+ * for lights.
+ */
class CLightManager
{
public:
@@ -123,7 +139,7 @@ public:
//! Clears and disables all lights
void FlushLights();
//! Creates a new dynamic light and returns its index (lightRank)
- int CreateLight();
+ int CreateLight(LightPriority priority = LIGHT_PRI_LOW);
//! Deletes and disables the given dynamic light
bool DeleteLight(int lightRank);
//! Sets the light parameters for dynamic light
@@ -161,7 +177,7 @@ public:
//! Sets the destination color for dynamic light's color progression
bool SetLightColor(int lightRank, const Color &color);
//! Returns current light color
- Color GetLightColor(int lightRank);
+ Color GetLightColor(int lightRank);
//! Sets the rate of change for dynamic light colors (RGB)
bool SetLightColorSpeed(int lightRank, float speed);
@@ -170,7 +186,7 @@ public:
//! Updates (recalculates) all dynamic lights
void UpdateLights();
//! Enables or disables dynamic lights affecting the given object type
- void UpdateLightsEnableState(EngineObjectType type);
+ void UpdateDeviceLights(EngineObjectType type);
protected:
CInstanceManager* m_iMan;
@@ -181,6 +197,8 @@ protected:
float m_time;
//! List of dynamic lights
std::vector<DynamicLight> m_dynLights;
+ //! Map of current light allotment: graphics light -> dynamic light
+ std::vector<int> m_lightMap;
};
}; // namespace Gfx
diff --git a/src/graphics/engine/planet.cpp b/src/graphics/engine/planet.cpp
index 0ac2524..3b9aa6c 100644
--- a/src/graphics/engine/planet.cpp
+++ b/src/graphics/engine/planet.cpp
@@ -147,7 +147,8 @@ void CPlanet::Draw()
}
void CPlanet::Create(int mode, Math::Point start, float dim, float speed,
- float dir, const std::string& name, Math::Point uv1, Math::Point uv2)
+ float dir, const std::string& name, Math::Point uv1, Math::Point uv2,
+ bool transparent)
{
if (mode < 0) mode = 0;
if (mode > 1) mode = 1;
@@ -164,7 +165,7 @@ void CPlanet::Create(int mode, Math::Point start, float dim, float speed,
planet.uv1 = uv1;
planet.uv2 = uv2;
- planet.transparent = planet.name.find("planet") != std::string::npos;
+ planet.transparent = transparent;
m_planet[mode].push_back(planet);
diff --git a/src/graphics/engine/planet.h b/src/graphics/engine/planet.h
index 82c3aea..1b16da0 100644
--- a/src/graphics/engine/planet.h
+++ b/src/graphics/engine/planet.h
@@ -91,7 +91,8 @@ public:
bool EventProcess(const Event &event);
//! Creates a new planet
void Create(int mode, Math::Point start, float dim, float speed, float dir,
- const std::string& name, Math::Point uv1, Math::Point uv2);
+ const std::string& name, Math::Point uv1, Math::Point uv2,
+ bool transparent);
//! Indicates if there is at least one planet
bool PlanetExist();
//! Load all the textures for the planets
diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp
index d2ddecc..4c22a32 100644
--- a/src/graphics/engine/terrain.cpp
+++ b/src/graphics/engine/terrain.cpp
@@ -74,7 +74,7 @@ CTerrain::~CTerrain()
}
bool CTerrain::Generate(int mosaicCount, int brickCountPow2, float brickSize,
- float vision, int depth, float hardness)
+ float vision, int depth, float hardness)
{
m_mosaicCount = mosaicCount;
m_brickCount = 1 << brickCountPow2;
@@ -162,8 +162,8 @@ void CTerrain::FlushMaterials()
}
void CTerrain::AddMaterial(int id, const std::string& texName, const Math::Point &uv,
- int up, int right, int down, int left,
- float hardness)
+ int up, int right, int down, int left,
+ float hardness)
{
InitMaterialPoints();
@@ -207,25 +207,41 @@ bool CTerrain::LoadResources(const std::string& fileName)
ImageData *data = img.GetData();
- int size = (m_mosaicCount*m_brickCount)+1;
-
- m_resources.clear();
+ int size = (m_mosaicCount*m_brickCount)+1;
- std::vector<unsigned char>(3*size*size).swap(m_resources);
+ std::vector<unsigned char>(size*size).swap(m_resources);
- if ( (data->surface->w != size) || (data->surface->h != size) ||
- (data->surface->format->BytesPerPixel != 3) )
+ if ( (data->surface->w != size) || (data->surface->h != size) )
{
GetLogger()->Error("Invalid resource file\n");
return false;
}
- unsigned char* pixels = static_cast<unsigned char*>(data->surface->pixels);
- int pitch = data->surface->pitch;
-
- for (int y = 0; y < size; y++)
+ for (int x = 0; x < size; ++x)
{
- memcpy(&m_resources[3*size*y], &pixels[pitch*y], 3*size);
+ for (int y = 0; y < size; ++y)
+ {
+ Gfx::IntColor pixel = img.GetPixelInt(Math::IntPoint(x, size - y - 1));
+ TerrainRes res = TR_NULL;
+
+ // values from original bitmap palette
+ if (pixel.r == 255 && pixel.g == 0 && pixel.b == 0)
+ res = TR_STONE;
+ else if (pixel.r == 255 && pixel.g == 255 && pixel.b == 0)
+ res = TR_URANIUM;
+ else if (pixel.r == 0 && pixel.g == 255 && pixel.b == 0)
+ res = TR_POWER;
+ else if (pixel.r == 0 && pixel.g == 204 && pixel.b == 0)
+ res = TR_KEY_A;
+ else if (pixel.r == 51 && pixel.g == 204 && pixel.b == 0)
+ res = TR_KEY_B;
+ else if (pixel.r == 102 && pixel.g == 204 && pixel.b == 0)
+ res = TR_KEY_C;
+ else if (pixel.r == 153 && pixel.g == 204 && pixel.b == 0)
+ res = TR_KEY_D;
+
+ m_resources[x+size*y] = static_cast<unsigned char>(res);
+ }
}
return true;
@@ -243,23 +259,9 @@ TerrainRes CTerrain::GetResource(const Math::Vector &p)
y < 0 || y > m_mosaicCount*m_brickCount )
return TR_NULL;
- int size = (m_mosaicCount*m_brickCount)+1;
-
- int resR = m_resources[3*x+3*size*(size-y-1)];
- int resG = m_resources[3*x+3*size*(size-y-1)+1];
- int resB = m_resources[3*x+3*size*(size-y-1)+2];
-
- if (resR == 255 && resG == 0 && resB == 0) return TR_STONE;
- if (resR == 255 && resG == 255 && resB == 0) return TR_URANIUM;
- if (resR == 0 && resG == 255 && resB == 0) return TR_POWER;
-
- // TODO key res values
- //if (ress == 24) return TR_KEY_A; // ~green?
- //if (ress == 25) return TR_KEY_B; // ~green?
- //if (ress == 26) return TR_KEY_C; // ~green?
- //if (ress == 27) return TR_KEY_D; // ~green?
+ int size = (m_mosaicCount*m_brickCount)+1;
- return TR_NULL;
+ return static_cast<TerrainRes>( m_resources[x+size*y] );
}
void CTerrain::FlushRelief()
@@ -287,22 +289,21 @@ bool CTerrain::LoadRelief(const std::string &fileName, float scaleRelief,
int size = (m_mosaicCount*m_brickCount)+1;
- if ( (data->surface->w != size) || (data->surface->h != size) ||
- (data->surface->format->BytesPerPixel != 3) )
+ if ( (data->surface->w != size) || (data->surface->h != size) )
{
GetLogger()->Error("Invalid relief file!\n");
return false;
}
- unsigned char* pixels = static_cast<unsigned char*>(data->surface->pixels);
- int pitch = data->surface->pitch;
-
float limit = 0.9f;
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
- float level = (255 - pixels[3*x+pitch*(size-y-1)]) * scaleRelief;
+ Gfx::IntColor color = img.GetPixelInt(Math::IntPoint(x, size - y - 1));
+
+ float avg = (color.r + color.g + color.b) / 3.0f; // to be sure it is grayscale
+ float level = (255.0f - avg) * scaleRelief;
float dist = Math::Max(fabs(static_cast<float>(x-size/2)),
fabs(static_cast<float>(y-size/2)));
@@ -492,8 +493,8 @@ VertexTex2 CTerrain::GetVertex(int x, int y, int step)
+-------------------> x
\endverbatim */
bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
- const Material &mat,
- float min, float max)
+ const Material &mat,
+ float min, float max)
{
std::string texName1;
std::string texName2;
@@ -1057,8 +1058,8 @@ bool CTerrain::InitMaterials(int id)
}
bool CTerrain::GenerateMaterials(int *id, float min, float max,
- float slope, float freq,
- Math::Vector center, float radius)
+ float slope, float freq,
+ Math::Vector center, float radius)
{
static char random[100] =
{
@@ -1454,13 +1455,14 @@ bool CTerrain::AdjustToFloor(Math::Vector &pos, bool brut, bool water)
}
/**
- * @returns \c false if the initial coordinate was outside terrain area; \c true otherwise
+ * \param pos position to adjust
+ * \returns \c false if the initial coordinate was outside terrain area; \c true otherwise
*/
bool CTerrain::AdjustToStandardBounds(Math::Vector& pos)
{
bool ok = true;
- // TODO: _TEEN ... * 0.98f;
+ // In _TEEN there used to be a limit of 0.98f
float limit = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f*0.92f;
if (pos.x < -limit)
@@ -1491,8 +1493,9 @@ bool CTerrain::AdjustToStandardBounds(Math::Vector& pos)
}
/**
- * @param margin margin to the terrain border
- * @returns \c false if the initial coordinate was outside terrain area; \c true otherwise
+ * \param pos position to adjust
+ * \param margin margin to the terrain border
+ * \returns \c false if the initial coordinate was outside terrain area; \c true otherwise
*/
bool CTerrain::AdjustToBounds(Math::Vector& pos, float margin)
{
@@ -1718,14 +1721,14 @@ float CTerrain::GetFlatZoneRadius(Math::Vector center, float max)
float ref = GetFloorLevel(center, true);
Math::Point c(center.x, center.z);
float radius = 1.0f;
-
+
while (radius <= max)
{
angle = 0.0f;
int nb = static_cast<int>(2.0f*Math::PI*radius);
if (nb < 8) nb = 8;
- Math::Point p (center.x+radius, center.z);
+ Math::Point p (center.x+radius, center.z);
for (int i = 0; i < nb; i++)
{
Math::Point result = Math::RotatePoint(c, angle, p);
diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp
index a77a6fd..4deeb53 100644
--- a/src/graphics/engine/text.cpp
+++ b/src/graphics/engine/text.cpp
@@ -279,18 +279,14 @@ float CText::GetHeight(FontType font, float size)
float CText::GetStringWidth(const std::string &text,
std::map<unsigned int, FontMetaChar> &format, float size)
{
- // TODO assert was commented as new code uses map not vector and if's size doesn't have to match text length
- // this has to be tested if it's correct
- //assert(StrUtils::Utf8StringLength(text) == format.size());
-
float width = 0.0f;
unsigned int index = 0;
unsigned int fmtIndex = 0;
while (index < text.length())
{
FontType font = FONT_COLOBOT;
- if (format.count(fmtIndex))
- font = static_cast<FontType>(format[fmtIndex] & FONT_MASK_FONT);
+ if (format.count(fmtIndex))
+ font = static_cast<FontType>(format[fmtIndex] & FONT_MASK_FONT);
UTF8Char ch;
@@ -350,10 +346,6 @@ float CText::GetCharWidth(UTF8Char ch, FontType font, float size, float offset)
int CText::Justify(const std::string &text, std::map<unsigned int, FontMetaChar> &format,
float size, float width)
{
- // TODO assert was commented as new code uses map not vector and if's size doesn't have to match text length
- // this has to be tested if it's correct
- //assert(StrUtils::Utf8StringLength(text) == format.size());
-
float pos = 0.0f;
int cut = 0;
unsigned int index = 0;
@@ -361,8 +353,8 @@ int CText::Justify(const std::string &text, std::map<unsigned int, FontMetaChar>
while (index < text.length())
{
FontType font = FONT_COLOBOT;
- if (format.count(fmtIndex))
- font = static_cast<FontType>(format[fmtIndex] & FONT_MASK_FONT);
+ if (format.count(fmtIndex))
+ font = static_cast<FontType>(format[fmtIndex] & FONT_MASK_FONT);
UTF8Char ch;
@@ -437,18 +429,14 @@ int CText::Justify(const std::string &text, FontType font, float size, float wid
int CText::Detect(const std::string &text, std::map<unsigned int, FontMetaChar> &format,
float size, float offset)
{
- // TODO assert was commented as new code uses map not vector and if's size doesn't have to match text length
- // this has to be tested if it's correct
- //assert(StrUtils::Utf8StringLength(text) == format.size());
-
float pos = 0.0f;
unsigned int index = 0;
unsigned int fmtIndex = 0;
while (index < text.length())
{
FontType font = FONT_COLOBOT;
- if (format.count(fmtIndex))
- font = static_cast<FontType>(format[fmtIndex] & FONT_MASK_FONT);
+ if (format.count(fmtIndex))
+ font = static_cast<FontType>(format[fmtIndex] & FONT_MASK_FONT);
// TODO: if (font == FONT_BUTTON)
if (font == FONT_BUTTON) continue;
@@ -514,13 +502,8 @@ int CText::Detect(const std::string &text, FontType font, float size, float offs
void CText::DrawString(const std::string &text, std::map<unsigned int, FontMetaChar> &format,
float size, Math::Point pos, float width, int eol)
{
- // TODO assert was commented as new code uses map not vector and if's size doesn't have to match text length
- // this has to be tested if it's correct
- //assert(StrUtils::Utf8StringLength(text) == format.size());
-
m_engine->SetState(ENG_RSTATE_TEXT);
- FontType font = FONT_COLOBOT;
float start = pos.x;
unsigned int fmtIndex = 0;
@@ -530,8 +513,8 @@ void CText::DrawString(const std::string &text, std::map<unsigned int, FontMetaC
for (auto it = chars.begin(); it != chars.end(); ++it)
{
FontType font = FONT_COLOBOT;
- if (format.count(fmtIndex))
- font = static_cast<FontType>(format[fmtIndex] & FONT_MASK_FONT);
+ if (format.count(fmtIndex))
+ font = static_cast<FontType>(format[fmtIndex] & FONT_MASK_FONT);
// TODO: if (font == FONT_BUTTON)
if (font == FONT_BUTTON) continue;
@@ -566,17 +549,18 @@ void CText::DrawString(const std::string &text, std::map<unsigned int, FontMetaC
void CText::StringToUTFCharList(const std::string &text, std::vector<UTF8Char> &chars)
{
unsigned int index = 0;
- while (index < text.length())
+ unsigned int totalLength = text.length();
+ while (index < totalLength)
{
UTF8Char ch;
int len = StrUtils::Utf8CharSizeAt(text, index);
if (len >= 1)
- ch.c1 = text[index];
+ ch.c1 = text[index];
if (len >= 2)
- ch.c2 = text[index+1];
+ ch.c2 = text[index+1];
if (len >= 3)
- ch.c3 = text[index+2];
+ ch.c3 = text[index+2];
index += len;
diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h
index cc18f55..7fa8768 100644
--- a/src/graphics/engine/text.h
+++ b/src/graphics/engine/text.h
@@ -149,9 +149,12 @@ enum FontMask
struct UTF8Char
{
char c1, c2, c3;
+ // Padding for 4-byte alignment
+ // It also seems to fix some problems reported by valgrind
+ char pad;
explicit UTF8Char(char ch1 = '\0', char ch2 = '\0', char ch3 = '\0')
- : c1(ch1), c2(ch2), c3(ch3) {}
+ : c1(ch1), c2(ch2), c3(ch3), pad('\0') {}
inline bool operator<(const UTF8Char &other) const
{
diff --git a/src/graphics/engine/water.cpp b/src/graphics/engine/water.cpp
index 81034a3..18811eb 100644
--- a/src/graphics/engine/water.cpp
+++ b/src/graphics/engine/water.cpp
@@ -279,11 +279,9 @@ void CWater::DrawBack()
material.ambient = m_ambient;
m_engine->SetMaterial(material);
- m_engine->SetTexture("", 0); // TODO: disable texturing
-
CDevice* device = m_engine->GetDevice();
- m_engine->SetState(ENG_RSTATE_NORMAL);
+ m_engine->SetState(Gfx::ENG_RSTATE_OPAQUE_COLOR);
float deep = m_engine->GetDeepView(0);
m_engine->SetDeepView(deep*2.0f, 0);
@@ -310,17 +308,14 @@ void CWater::DrawBack()
p1.y = -50.0f;
p2.y = m_level;
- Math::Vector n;
- n.x = (lookat.x-eye.x)/dist;
- n.z = (lookat.z-eye.z)/dist;
- n.y = 0.0f;
+ Gfx::Color white = Gfx::Color(1.0f, 1.0f, 1.0f, 0.0f);
- Vertex vertices[4] =
+ VertexCol vertices[4] =
{
- Vertex(Math::Vector(p1.x, p2.y, p1.z), n),
- Vertex(Math::Vector(p1.x, p1.y, p1.z), n),
- Vertex(Math::Vector(p2.x, p2.y, p2.z), n),
- Vertex(Math::Vector(p2.x, p1.y, p2.z), n)
+ VertexCol(Math::Vector(p1.x, p2.y, p1.z), white),
+ VertexCol(Math::Vector(p1.x, p1.y, p1.z), white),
+ VertexCol(Math::Vector(p2.x, p2.y, p2.z), white),
+ VertexCol(Math::Vector(p2.x, p1.y, p2.z), white)
};
device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertices, 4);
@@ -480,8 +475,8 @@ void CWater::CreateLine(int x, int y, int len)
}
void CWater::Create(WaterType type1, WaterType type2, const std::string& fileName,
- Color diffuse, Color ambient,
- float level, float glint, Math::Vector eddy)
+ Color diffuse, Color ambient,
+ float level, float glint, Math::Vector eddy)
{
m_type[0] = type1;
m_type[1] = type2;
diff --git a/src/graphics/engine/water.h b/src/graphics/engine/water.h
index a43c740..21d96d4 100644
--- a/src/graphics/engine/water.h
+++ b/src/graphics/engine/water.h
@@ -169,10 +169,10 @@ protected:
protected:
CInstanceManager* m_iMan;
- CEngine* m_engine;
- CDevice* m_device;
- CTerrain* m_terrain;
- CParticle* m_particule;
+ CEngine* m_engine;
+ CDevice* m_device;
+ CTerrain* m_terrain;
+ CParticle* m_particule;
CSoundInterface* m_sound;
WaterType m_type[2];
@@ -184,9 +184,9 @@ protected:
//! Amplitude of swirls
Math::Vector m_eddy;
//! Diffuse color
- Color m_diffuse;
+ Color m_diffuse;
//! Ambient color
- Color m_ambient;
+ Color m_ambient;
float m_time;
float m_lastLava;
int m_subdiv;
@@ -201,7 +201,7 @@ protected:
bool m_draw;
bool m_lava;
- Color m_color;
+ Color m_color;
};
diff --git a/src/graphics/opengl/README.txt b/src/graphics/opengl/README.txt
index 596871d..c62166b 100644
--- a/src/graphics/opengl/README.txt
+++ b/src/graphics/opengl/README.txt
@@ -1,7 +1,7 @@
/**
- * \dir graphics/opengl
+ * \dir src/graphics/opengl
* \brief OpenGL engine implementation
*
* Contains the concrete implementation using OpenGL of abstract CDevice class
* from src/graphics/core
- */ \ No newline at end of file
+ */
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index bbad0a7..58b7ece 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -117,9 +117,6 @@ bool CGLDevice::Create()
// So turn it on permanently
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
- // To use separate specular color in drawing primitives
- glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
-
// To avoid problems with scaling & lighting
glEnable(GL_RESCALE_NORMAL);
@@ -136,13 +133,13 @@ bool CGLDevice::Create()
glGetIntegerv(GL_MAX_LIGHTS, &numLights);
m_lights = std::vector<Light>(numLights, Light());
- m_lightsEnabled = std::vector<bool> (numLights, false);
+ m_lightsEnabled = std::vector<bool> (numLights, false);
int maxTextures = 0;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTextures);
m_currentTextures = std::vector<Texture> (maxTextures, Texture());
- m_texturesEnabled = std::vector<bool> (maxTextures, false);
+ m_texturesEnabled = std::vector<bool> (maxTextures, false);
m_textureStageParams = std::vector<TextureStageParams>(maxTextures, TextureStageParams());
GetLogger()->Info("CDevice created successfully\n");
@@ -326,33 +323,39 @@ void CGLDevice::UpdateLightPosition(int index)
assert(index >= 0);
assert(index < static_cast<int>( m_lights.size() ));
- if ((! m_lighting) || (! m_lightsEnabled[index]))
- return;
-
glMatrixMode(GL_MODELVIEW);
+
glPushMatrix();
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
- glMultMatrixf(m_viewMat.Array());
+ Math::Matrix mat = m_viewMat;
+ mat.Set(1, 4, 0.0f);
+ mat.Set(2, 4, 0.0f);
+ mat.Set(3, 4, 0.0f);
+ glMultMatrixf(mat.Array());
+
+ if (m_lights[index].type == LIGHT_SPOT)
+ {
+ GLfloat direction[4] = { -m_lights[index].direction.x, -m_lights[index].direction.y, -m_lights[index].direction.z, 1.0f };
+ glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
+ }
if (m_lights[index].type == LIGHT_DIRECTIONAL)
{
- GLfloat position[4] = { m_lights[index].direction.x, m_lights[index].direction.y, m_lights[index].direction.z, 0.0f };
+ GLfloat position[4] = { -m_lights[index].direction.x, -m_lights[index].direction.y, -m_lights[index].direction.z, 0.0f };
glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
}
else
{
+ glLoadIdentity();
+ glScalef(1.0f, 1.0f, -1.0f);
+ glMultMatrixf(m_viewMat.Array());
+
GLfloat position[4] = { m_lights[index].position.x, m_lights[index].position.y, m_lights[index].position.z, 1.0f };
glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
}
- if (m_lights[index].type == LIGHT_SPOT)
- {
- GLfloat direction[4] = { m_lights[index].direction.x, m_lights[index].direction.y, m_lights[index].direction.z, 0.0f };
- glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
- }
-
glPopMatrix();
}
@@ -371,7 +374,10 @@ void CGLDevice::SetLightEnabled(int index, bool enabled)
m_lightsEnabled[index] = enabled;
- glEnable(GL_LIGHT0 + index);
+ if (enabled)
+ glEnable(GL_LIGHT0 + index);
+ else
+ glDisable(GL_LIGHT0 + index);
}
bool CGLDevice::GetLightEnabled(int index)
@@ -408,8 +414,6 @@ Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &par
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
glGenTextures(1, &result.id);
glBindTexture(GL_TEXTURE_2D, result.id);
@@ -546,10 +550,7 @@ Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &par
// Restore the previous state of 1st stage
- if (m_currentTextures[0].Valid())
- glBindTexture(GL_TEXTURE_2D, m_currentTextures[0].id);
- else
- glBindTexture(GL_TEXTURE_2D, 0);
+ glBindTexture(GL_TEXTURE_2D, m_currentTextures[0].id);
if ( (! m_texturing) || (! m_texturesEnabled[0]) )
glDisable(GL_TEXTURE_2D);
@@ -559,7 +560,7 @@ Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &par
void CGLDevice::DestroyTexture(const Texture &texture)
{
- std::set<Texture>::iterator it = m_allTextures.find(texture);
+ auto it = m_allTextures.find(texture);
if (it != m_allTextures.end())
m_allTextures.erase(it);
@@ -575,10 +576,12 @@ void CGLDevice::DestroyTexture(const Texture &texture)
void CGLDevice::DestroyAllTextures()
{
- std::set<Texture> allCopy = m_allTextures;
- std::set<Texture>::iterator it;
- for (it = allCopy.begin(); it != allCopy.end(); ++it)
- DestroyTexture(*it);
+ for (auto it = m_allTextures.begin(); it != m_allTextures.end(); ++it)
+ glDeleteTextures(1, &(*it).id);
+
+ // Unbind all texture stages
+ for (int index = 0; index < static_cast<int>( m_currentTextures.size() ); ++index)
+ SetTexture(index, Texture());
}
int CGLDevice::GetMaxTextureCount()
@@ -595,25 +598,19 @@ void CGLDevice::SetTexture(int index, const Texture &texture)
assert(index >= 0);
assert(index < static_cast<int>( m_currentTextures.size() ));
- // Enable the given texture stage
- glActiveTexture(GL_TEXTURE0 + index);
- glEnable(GL_TEXTURE_2D);
+ bool same = m_currentTextures[index].id == texture.id;
- m_currentTextures[index] = texture; // remember the change
+ m_currentTextures[index] = texture; // remember the new value
- if (! texture.Valid())
- {
- glBindTexture(GL_TEXTURE_2D, 0); // unbind texture
- }
- else
- {
- glBindTexture(GL_TEXTURE_2D, texture.id); // bind the texture
- SetTextureStageParams(index, m_textureStageParams[index]); // texture stage params need to be re-set for the new texture
- }
+ if (same)
+ return; // nothing to do
- // Disable the stage if it is set so
- if ( (! m_texturing) || (! m_texturesEnabled[index]) )
- glDisable(GL_TEXTURE_2D);
+ glEnable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE0 + index);
+ glBindTexture(GL_TEXTURE_2D, texture.id);
+
+ // Params need to be updated for the new bound texture
+ SetTextureStageParams(index, m_textureStageParams[index]);
}
void CGLDevice::SetTexture(int index, unsigned int textureId)
@@ -621,17 +618,17 @@ void CGLDevice::SetTexture(int index, unsigned int textureId)
assert(index >= 0);
assert(index < static_cast<int>( m_currentTextures.size() ));
- // Enable the given texture stage
- glActiveTexture(GL_TEXTURE0 + index);
- glEnable(GL_TEXTURE_2D);
+ if (m_currentTextures[index].id == textureId)
+ return; // nothing to do
m_currentTextures[index].id = textureId;
+ glEnable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE0 + index);
glBindTexture(GL_TEXTURE_2D, textureId);
- // Disable the stage if it is set so
- if ( (! m_texturing) || (! m_texturesEnabled[index]) )
- glDisable(GL_TEXTURE_2D);
+ // Params need to be updated for the new bound texture
+ SetTextureStageParams(index, m_textureStageParams[index]);
}
/**
@@ -649,8 +646,13 @@ void CGLDevice::SetTextureEnabled(int index, bool enabled)
assert(index >= 0);
assert(index < static_cast<int>( m_currentTextures.size() ));
+ bool same = m_texturesEnabled[index] == enabled;
+
m_texturesEnabled[index] = enabled;
+ if (same)
+ return; // nothing to do
+
glActiveTexture(GL_TEXTURE0 + index);
if (enabled)
glEnable(GL_TEXTURE_2D);
@@ -683,10 +685,8 @@ void CGLDevice::SetTextureStageParams(int index, const TextureStageParams &param
return;
// Enable the given stage
- glActiveTexture(GL_TEXTURE0 + index);
glEnable(GL_TEXTURE_2D);
-
- glBindTexture(GL_TEXTURE_2D, m_currentTextures[index].id);
+ glActiveTexture(GL_TEXTURE0 + index);
// To save some trouble
if ( (params.colorOperation == TEX_MIX_OPER_DEFAULT) &&
@@ -804,7 +804,41 @@ after_tex_operations:
else assert(false);
// Disable the stage if it is set so
- if ( (! m_texturing) || (! m_texturesEnabled[index]) )
+ if ( (! m_texturing) || (! m_texturesEnabled[0]) )
+ glDisable(GL_TEXTURE_2D);
+}
+
+void CGLDevice::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wrapT)
+{
+ assert(index >= 0);
+ assert(index < static_cast<int>( m_currentTextures.size() ));
+
+ // Remember the settings
+ m_textureStageParams[index].wrapS = wrapS;
+ m_textureStageParams[index].wrapT = wrapT;
+
+ // Don't actually do anything if texture not set
+ if (! m_currentTextures[index].Valid())
+ return;
+
+ // Enable the given stage
+ glEnable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE0 + index);
+
+ if (wrapS == TEX_WRAP_CLAMP)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ else if (wrapS == TEX_WRAP_REPEAT)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ else assert(false);
+
+ if (wrapT == TEX_WRAP_CLAMP)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ else if (wrapT == TEX_WRAP_REPEAT)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ else assert(false);
+
+ // Disable the stage if it is set so
+ if ( (! m_texturing) || (! m_texturesEnabled[0]) )
glDisable(GL_TEXTURE_2D);
}
@@ -866,48 +900,68 @@ GLenum TranslateGfxPrimitive(PrimitiveType type)
void CGLDevice::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount)
{
- glBegin(TranslateGfxPrimitive(type));
+ Vertex* vs = const_cast<Vertex*>(vertices);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].coord));
+
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].normal));
+
+ glClientActiveTexture(GL_TEXTURE0);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].texCoord));
glColor3f(1.0f, 1.0f, 1.0f);
- for (int i = 0; i < vertexCount; ++i)
- {
- glNormal3fv(const_cast<GLfloat*>(vertices[i].normal.Array()));
- glMultiTexCoord2fv(GL_TEXTURE0, const_cast<GLfloat*>(vertices[i].texCoord.Array()));
- glVertex3fv(const_cast<GLfloat*>(vertices[i].coord.Array()));
- }
+ glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
- glEnd();
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0
}
void CGLDevice::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
{
- glBegin(TranslateGfxPrimitive(type));
+ VertexCol* vs = const_cast<VertexCol*>(vertices);
- for (int i = 0; i < vertexCount; ++i)
- {
- glColor4fv(const_cast<GLfloat*>(vertices[i].color.Array()));
- glVertex3fv(const_cast<GLfloat*>(vertices[i].coord.Array()));
- }
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].coord));
+
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].color));
- glEnd();
+ glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
}
void CGLDevice::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount)
{
- glBegin(TranslateGfxPrimitive(type));
+ VertexTex2* vs = const_cast<VertexTex2*>(vertices);
- glColor3f(1.0f, 1.0f, 1.0f);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].coord));
- for (int i = 0; i < vertexCount; ++i)
- {
- glNormal3fv(const_cast<GLfloat*>(vertices[i].normal.Array()));
- glMultiTexCoord2fv(GL_TEXTURE0, const_cast<GLfloat*>(vertices[i].texCoord.Array()));
- glMultiTexCoord2fv(GL_TEXTURE1, const_cast<GLfloat*>(vertices[i].texCoord.Array()));
- glVertex3fv(const_cast<GLfloat*>(vertices[i].coord.Array()));
- }
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].normal));
+
+ glClientActiveTexture(GL_TEXTURE0);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].texCoord));
+
+ glClientActiveTexture(GL_TEXTURE1);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].texCoord2));
+
+ glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
- glEnd();
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1
+ glClientActiveTexture(GL_TEXTURE0);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
bool InPlane(Math::Vector normal, float originPlane, Math::Vector center, float radius)
diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h
index 1274ee9..282f141 100644
--- a/src/graphics/opengl/gldevice.h
+++ b/src/graphics/opengl/gldevice.h
@@ -117,6 +117,8 @@ public:
virtual void SetTextureStageParams(int index, const TextureStageParams &params);
virtual TextureStageParams GetTextureStageParams(int index);
+ virtual void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT);
+
virtual void SetTextureFactor(const Color &color);
virtual Color GetTextureFactor();
diff --git a/src/math/README.txt b/src/math/README.txt
index fd34dcb..26069aa 100644
--- a/src/math/README.txt
+++ b/src/math/README.txt
@@ -1,5 +1,5 @@
/**
- * \dir math
+ * \dir src/math
* \brief Common mathematical structures and functions
*/
@@ -9,4 +9,4 @@
*
* This namespace was created to avoid clashing with old code, but now it still serves,
* defining a border between math and non-math-related code.
- */ \ No newline at end of file
+ */
diff --git a/src/math/geometry.h b/src/math/geometry.h
index f086e2d..ee6fc52 100644
--- a/src/math/geometry.h
+++ b/src/math/geometry.h
@@ -237,6 +237,7 @@ inline float RotateAngle(const Math::Point &center, const Math::Point &p1, const
//! Loads view matrix from the given vectors
/**
+ * \param mat result matrix
* \param from origin
* \param at view direction
* \param worldUp up vector
@@ -304,6 +305,7 @@ inline void LoadViewMatrix(Math::Matrix &mat, const Math::Vector &from,
//! Loads a perspective projection matrix
/**
+ * \param mat result matrix
* \param fov field of view in radians
* \param aspect aspect ratio (width / height)
* \param nearPlane distance to near cut plane
@@ -328,6 +330,7 @@ inline void LoadProjectionMatrix(Math::Matrix &mat, float fov = Math::PI / 2.0f,
//! Loads an othogonal projection matrix
/**
+ * \param mat result matrix
* \param left,right coordinates for left and right vertical clipping planes
* \param bottom,top coordinates for bottom and top horizontal clipping planes
* \param zNear,zFar distance to nearer and farther depth clipping planes
@@ -590,7 +593,7 @@ inline Math::Vector Transform(const Math::Matrix &m, const Math::Vector &p)
//! Calculates the projection of the point \a p on a straight line \a a to \a b
/**
- * \param point to project
+ * \param p point to project
* \param a,b two ends of the line
*/
inline Math::Vector Projection(const Math::Vector &a, const Math::Vector &b, const Math::Vector &p)
diff --git a/src/object/README.txt b/src/object/README.txt
index f3bad23..fe946db 100644
--- a/src/object/README.txt
+++ b/src/object/README.txt
@@ -1,7 +1,7 @@
/**
- * \dir object
+ * \dir src/object
* \brief Game engine
*
* Contains the main class of game engine - CRobotMain and the various in-game objects:
* CObject and related auto, motion and task subclasses.
- */ \ No newline at end of file
+ */
diff --git a/src/object/object.cpp b/src/object/object.cpp
index e93fa1e..0b1a39c 100644
--- a/src/object/object.cpp
+++ b/src/object/object.cpp
@@ -2244,14 +2244,12 @@ bool CObject::CreateInsect(Math::Vector pos, float angle, ObjectType type)
bool CObject::CreateShadowLight(float height, Gfx::Color color)
{
- Gfx::Light light;
- Math::Vector pos;
-
if ( !m_engine->GetLightMode() ) return true;
- pos = GetPosition(0);
+ Math::Vector pos = GetPosition(0);
m_shadowHeight = height;
+ Gfx::Light light;
light.type = Gfx::LIGHT_SPOT;
light.diffuse.r = color.r;
light.diffuse.g = color.g;
@@ -2262,12 +2260,10 @@ bool CObject::CreateShadowLight(float height, Gfx::Color color)
light.direction.x = 0.0f;
light.direction.y = -1.0f; // against the bottom
light.direction.z = 0.0f;
- //TODO Is this value correct
light.spotIntensity = 128;
light.attenuation0 = 1.0f;
light.attenuation1 = 0.0f;
light.attenuation2 = 0.0f;
- //TODO Is this value correct
light.spotAngle = 90;
m_shadowLight = m_lightMan->CreateLight();
@@ -2292,13 +2288,11 @@ int CObject::GetShadowLight()
bool CObject::CreateEffectLight(float height, Gfx::Color color)
{
- Gfx::Light light;
-
if ( !m_engine->GetLightMode() ) return true;
m_effectHeight = height;
- memset( &light, 0, sizeof(light) );
+ Gfx::Light light;
light.type = Gfx::LIGHT_SPOT;
light.diffuse.r = color.r;
light.diffuse.g = color.g;
@@ -2309,12 +2303,10 @@ bool CObject::CreateEffectLight(float height, Gfx::Color color)
light.direction.x = 0.0f;
light.direction.y = -1.0f; // against the bottom
light.direction.z = 0.0f;
- //TODO Is this value correct
- light.spotIntensity = 1.0f;
+ light.spotIntensity = 0.0f;
light.attenuation0 = 1.0f;
light.attenuation1 = 0.0f;
light.attenuation2 = 0.0f;
- //TODO Is this value correct
light.spotAngle = 90;
m_effectLight = m_lightMan->CreateLight();
diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp
index 3bc886b..62a157d 100644
--- a/src/object/robotmain.cpp
+++ b/src/object/robotmain.cpp
@@ -3911,10 +3911,12 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpFloat(line, "dir", 0.0f),
name,
Math::Point(uv1.x, uv1.z),
- Math::Point(uv2.x, uv2.z));
+ Math::Point(uv2.x, uv2.z),
+ strstr(name, "planet") != nullptr // TODO: add transparent op or modify textures
+ );
}
- if (Cmd(line, "FrontsizeName") && !resetObject)
+ if (Cmd(line, "ForegroundName") && !resetObject)
{
OpString(line, "image", name);
m_engine->SetForegroundName(name);
@@ -3963,7 +3965,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpTypeWater(line, "water", Gfx::WATER_TT),
name,
OpColor(line, "diffuse", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
- OpColor(line, "ambiant", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
+ OpColor(line, "ambient", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
OpFloat(line, "level", 100.0f)*UNIT,
OpFloat(line, "glint", 1.0f),
pos);
@@ -3979,7 +3981,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpString(line, "image", name);
m_cloud->Create(name,
OpColor(line, "diffuse", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
- OpColor(line, "ambiant", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
+ OpColor(line, "ambient", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
OpFloat(line, "level", 500.0f) * UNIT);
}
@@ -4846,7 +4848,7 @@ int CRobotMain::CreateLight(Math::Vector direction, Gfx::Color color)
light.type = Gfx::LIGHT_DIRECTIONAL;
light.diffuse = color;
light.direction = direction;
- int obj = m_lightMan->CreateLight();
+ int obj = m_lightMan->CreateLight(Gfx::LIGHT_PRI_HIGH);
m_lightMan->SetLight(obj, light);
return obj;
@@ -4869,7 +4871,7 @@ int CRobotMain::CreateSpot(Math::Vector pos, Gfx::Color color)
light.attenuation0 = 2.0f;
light.attenuation1 = 0.0f;
light.attenuation2 = 0.0f;
- int obj = m_lightMan->CreateLight();
+ int obj = m_lightMan->CreateLight(Gfx::LIGHT_PRI_HIGH);
m_lightMan->SetLight(obj, light);
return obj;
diff --git a/src/physics/README.txt b/src/physics/README.txt
index 4ad5989..c068d4d 100644
--- a/src/physics/README.txt
+++ b/src/physics/README.txt
@@ -1,4 +1,4 @@
/**
- * \dir physics
+ * \dir src/physics
* \brief Physics engine
- */ \ No newline at end of file
+ */
diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp
index 40dbdc7..a3c680b 100644
--- a/src/physics/physics.cpp
+++ b/src/physics/physics.cpp
@@ -3016,7 +3016,12 @@ void CPhysics::FrameParticle(float aTime, float rTime)
effectLight = m_object->GetEffectLight();
if ( effectLight != -1 )
{
- if ( bFlash )
+ /*
+ * TODO: this is supposed to flash lights of robot without power,
+ * but doesn't work correctly (e.g. beginning of scene201).
+ * Commenting out for the time being.
+ */
+ /*if ( bFlash )
{
intensity = 0.0f;
if ( Math::Rand() < 0.5f ) intensity = 1.0f;
@@ -3024,9 +3029,9 @@ void CPhysics::FrameParticle(float aTime, float rTime)
m_lightMan->SetLightIntensitySpeed(effectLight, 10000.0f);
}
else
- {
+ {*/
m_lightMan->SetLightIntensity(effectLight, 0.0f);
- }
+ /*}*/
}
}
diff --git a/src/sound/README.txt b/src/sound/README.txt
index fa7bbad..fa2f531 100644
--- a/src/sound/README.txt
+++ b/src/sound/README.txt
@@ -1,4 +1,4 @@
/**
- * \dir sound
+ * \dir src/sound
* \brief Sound module - playing sounds and music
- */ \ No newline at end of file
+ */
diff --git a/src/ui/README.txt b/src/ui/README.txt
index 9814ef0..a159ed5 100644
--- a/src/ui/README.txt
+++ b/src/ui/README.txt
@@ -1,4 +1,4 @@
/**
- * \dir ui
+ * \dir src/ui
* \brief 2D user interface controls
- */ \ No newline at end of file
+ */