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
dev-ui
Piotr Dziwinski 2012-09-29 10:40:11 +02:00
parent 77952a85e6
commit 677ce3960c
10 changed files with 212 additions and 139 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
bool same = m_currentTextures[index].id == texture.id;
m_currentTextures[index] = texture; // remember the new value
if (same)
return; // nothing to do
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0 + index);
glBindTexture(GL_TEXTURE_2D, texture.id);
m_currentTextures[index] = texture; // remember the change
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
}
// 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]);
}
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));
glEnd();
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);
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)

View File

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