From 677ce3960cd13cbf994311c76d75b343b22fd480 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sat, 29 Sep 2012 10:40:11 +0200 Subject: 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 --- src/app/app.cpp | 12 +-- src/graphics/core/device.h | 3 + src/graphics/core/texture.h | 34 ++++---- src/graphics/core/vertex.h | 21 ++++- src/graphics/engine/engine.cpp | 56 +++++++------ src/graphics/engine/engine.h | 2 + src/graphics/engine/text.cpp | 42 +++------- src/graphics/engine/text.h | 5 +- src/graphics/opengl/gldevice.cpp | 172 +++++++++++++++++++++++++-------------- src/graphics/opengl/gldevice.h | 2 + 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( 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 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 &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(format[fmtIndex] & FONT_MASK_FONT); + if (format.count(fmtIndex)) + font = static_cast(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 &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 while (index < text.length()) { FontType font = FONT_COLOBOT; - if (format.count(fmtIndex)) - font = static_cast(format[fmtIndex] & FONT_MASK_FONT); + if (format.count(fmtIndex)) + font = static_cast(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 &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(format[fmtIndex] & FONT_MASK_FONT); + if (format.count(fmtIndex)) + font = static_cast(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 &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(format[fmtIndex] & FONT_MASK_FONT); + if (format.count(fmtIndex)) + font = static_cast(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 &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::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 allCopy = m_allTextures; - std::set::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( 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( 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( 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( 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 ¶m 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( 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(vertices); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].normal)); + + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].texCoord)); glColor3f(1.0f, 1.0f, 1.0f); - for (int i = 0; i < vertexCount; ++i) - { - glNormal3fv(const_cast(vertices[i].normal.Array())); - glMultiTexCoord2fv(GL_TEXTURE0, const_cast(vertices[i].texCoord.Array())); - glVertex3fv(const_cast(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(vertices); - for (int i = 0; i < vertexCount; ++i) - { - glColor4fv(const_cast(vertices[i].color.Array())); - glVertex3fv(const_cast(vertices[i].coord.Array())); - } + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].coord)); - glEnd(); + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&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(vertices); - glColor3f(1.0f, 1.0f, 1.0f); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].coord)); - for (int i = 0; i < vertexCount; ++i) - { - glNormal3fv(const_cast(vertices[i].normal.Array())); - glMultiTexCoord2fv(GL_TEXTURE0, const_cast(vertices[i].texCoord.Array())); - glMultiTexCoord2fv(GL_TEXTURE1, const_cast(vertices[i].texCoord.Array())); - glVertex3fv(const_cast(vertices[i].coord.Array())); - } + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].normal)); + + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord)); + + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&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 ¶ms); 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(); -- cgit v1.2.3-1-g7c22