summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-09-29 10:40:11 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-09-29 10:40:11 +0200
commit677ce3960cd13cbf994311c76d75b343b22fd480 (patch)
treeee2bab43ec29cdf94d8c1173ee022fe95c2a0222 /src
parent77952a85e63ca13dd9cfc93c7b6a271d7c91e59a (diff)
downloadcolobot-677ce3960cd13cbf994311c76d75b343b22fd480.tar.gz
colobot-677ce3960cd13cbf994311c76d75b343b22fd480.tar.bz2
colobot-677ce3960cd13cbf994311c76d75b343b22fd480.zip
Some fixes and optimizations
- fixed 2nd texture setting - added padding to some structs for faster access - changed rendering primitives to glDrawArrays() - optimized texture modesetting calls - fixed some valgrind errors
Diffstat (limited to 'src')
-rw-r--r--src/app/app.cpp12
-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/engine/engine.cpp56
-rw-r--r--src/graphics/engine/engine.h2
-rw-r--r--src/graphics/engine/text.cpp42
-rw-r--r--src/graphics/engine/text.h5
-rw-r--r--src/graphics/opengl/gldevice.cpp172
-rw-r--r--src/graphics/opengl/gldevice.h2
10 files changed, 211 insertions, 138 deletions
diff --git a/src/app/app.cpp b/src/app/app.cpp
index 00977d1..0b9aae6 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/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/engine/engine.cpp b/src/graphics/engine/engine.cpp
index d470b06..e34034d 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -217,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);
@@ -1854,8 +1859,7 @@ void CEngine::SetState(int state, const Color& color)
params.colorOperation = TEX_MIX_OPER_MODULATE;
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
params.colorArg2 = TEX_MIX_ARG_FACTOR;
- params.alphaOperation = TEX_MIX_OPER_DEFAULT;
- params.alphaOperation = TEX_MIX_OPER_REPLACE; // TODO: replace with src color ?
+ params.alphaOperation = TEX_MIX_OPER_DEFAULT; // TODO: replace with src color ?
m_device->SetTextureEnabled(0, true);
m_device->SetTextureStageParams(0, params);
@@ -2012,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)
@@ -2022,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
@@ -2032,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)
@@ -2182,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;
}
@@ -2815,7 +2826,6 @@ void CEngine::Draw3DScene()
if (m_shadowVisible)
{
- m_device->DebugHook();
m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN);
// Draw the terrain
diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h
index e188dea..6363fd3 100644
--- a/src/graphics/engine/engine.h
+++ b/src/graphics/engine/engine.h
@@ -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;
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/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index bffbc3a..58b7ece 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -414,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);
@@ -552,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);
@@ -565,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);
@@ -581,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()
@@ -601,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)
@@ -627,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]);
}
/**
@@ -655,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);
@@ -689,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) &&
@@ -810,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);
}
@@ -872,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));
- glEnd();
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].color));
+
+ 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();