Show textureunit.h syntax highlighted
/***************************************************************************
textureunit.h - Texture unit management
-------------------
begin : Sun Mar 30 2003
copyright : (C) 2003 by Reality Rift Studios
email : mattias@realityrift.com
***************************************************************************
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the NeoEngine, NeoDevOpenGL, textureunit.h
The Initial Developer of the Original Code is Mattias Jansson.
Portions created by Mattias Jansson are Copyright (C) 2003
Reality Rift Studios. All Rights Reserved.
***************************************************************************/
#ifndef __NEOGLTEXTUREUNIT_H
#define __NEOGLTEXTUREUNIT_H
/**
* \file textureunit.h
* Texture unit management
*/
#include "device.h"
#include "texture.h"
#include "extensions.h"
#include "statistics.h"
#include <neoengine/nemath.h>
namespace NeoOGL
{
/**
* \brief Data for a texture target
* \author Mattias Jansson (mattias@realityrift.com)
*/
class TextureTarget
{
public:
/*! Target */
GLenum m_eTarget;
/*! Current texture */
NeoOGL::Texture *m_pkTexture;
/*! Enabled flag */
bool m_bEnabled;
};
/**
* \brief Texture unit management
* \author Mattias Jansson (mattias@realityrift.com)
*/
class TextureUnit
{
friend class NeoOGL::Texture;
protected:
/*! Device */
Device *m_pkDevice;
/*! Current active texture unit */
static unsigned int s_uiCurUnit;
/*! Unit number */
unsigned int m_uiID;
/*! Texture targets */
TextureTarget m_akTarget[4];
/*! Current texture */
NeoOGL::Texture *m_pkTexture;
/*! Current UV layer */
unsigned int m_uiUV;
/*! Flag indicating we got texture transform matrix */
bool m_bGotTransform;
/*! Texture coordinate generation mode */
NeoEngine::TextureLayer::TEXCOORDGENERATION m_eTexGen;
public:
/**
* \param pkDevice Parent device object
* \param uiID Unit number
*/
TextureUnit( Device *pkDevice, unsigned int uiID );
/**
*/
virtual ~TextureUnit();
/**
* Set texture
* \param pkTexture Texture
*/
inline void SetTexture( NeoOGL::Texture *pkTexture )
{
if( pkTexture == m_pkTexture )
{
if( m_pkTexture && !m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_bEnabled )
{
SetActiveTextureUnit( m_uiID );
glEnable( m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_eTarget );
m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_bEnabled = true;
}
return;
}
SetActiveTextureUnit( m_uiID );
if( pkTexture )
{
if( m_pkTexture )
{
if( pkTexture->m_uiTargetIndex != m_pkTexture->m_uiTargetIndex )
{
//Disable old target
glDisable( m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_eTarget );
m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_bEnabled = false;
}
}
m_pkTexture = pkTexture;
glEnable( m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_eTarget );
glBindTexture( m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_eTarget, m_pkTexture->GetID() );
m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_pkTexture = m_pkTexture;
m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_bEnabled = true;
#ifdef NEOGL_ENABLE_STATISTICS
m_pkDevice->m_pkStats->m_auiTextureChanges[ m_uiID ]++;
std::vector< unsigned int >::iterator puiTexID = m_pkDevice->m_pkStats->m_vuiUniqueTextureIDs[ m_uiID ].begin();
std::vector< unsigned int >::iterator puiTexIDEnd = m_pkDevice->m_pkStats->m_vuiUniqueTextureIDs[ m_uiID ].end();
bool bFound = false;
int iCurTexture = m_pkTexture->GetID();
for( ; puiTexID != puiTexIDEnd; ++puiTexID )
{
if( *puiTexID == (unsigned int)iCurTexture )
{
bFound = true;
break;
}
}
if( !bFound )
m_pkDevice->m_pkStats->m_vuiUniqueTextureIDs[ m_uiID ].push_back( (unsigned int)iCurTexture );
#endif
}
else if( m_pkTexture )
{
//Disable target
glDisable( m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_eTarget );
m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_bEnabled = false;
m_pkTexture = 0;
#ifdef NEOGL_ENABLE_STATISTICS
m_pkDevice->m_pkStats->m_auiTextureChanges[ m_uiID ]++;
std::vector< unsigned int >::iterator puiTexID = m_pkDevice->m_pkStats->m_vuiUniqueTextureIDs[ m_uiID ].begin();
std::vector< unsigned int >::iterator puiTexIDEnd = m_pkDevice->m_pkStats->m_vuiUniqueTextureIDs[ m_uiID ].end();
bool bFound = false;
for( ; puiTexID != puiTexIDEnd; ++puiTexID )
{
if( *puiTexID == 0 )
{
bFound = true;
break;
}
}
if( !bFound )
m_pkDevice->m_pkStats->m_vuiUniqueTextureIDs[ m_uiID ].push_back( 0 );
#endif
}
}
/**
* Set blend mode
* \param uiSrcMode Source mode
* \param uiDstMode Destination mode
* \param fFactor Factor
* \return true if compatible mode, false if incompatible
*/
virtual bool SetBlendMode( unsigned int uiSrcMode, unsigned int uiDstMode, float fFactor );
/**
* Set new texture transform matrix
* \param pkMatrix New transform matrix, or 0 for identity
*/
inline void SetTransform( NeoEngine::Matrix *pkMatrix )
{
if( !m_bGotTransform && !pkMatrix )
return;
if( m_bGotTransform && !pkMatrix )
{
SetActiveTextureUnit( m_uiID );
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
m_bGotTransform = false;
}
else
{
SetActiveTextureUnit( m_uiID );
glMatrixMode( GL_TEXTURE );
neoglLoadMatrixf( (float*)*pkMatrix );
m_bGotTransform = true;
}
}
/**
* Set texture coordinate generation mode
* \param eTexCoordGen New mode
*/
inline void SetTexGen( NeoEngine::TextureLayer::TEXCOORDGENERATION eTexCoordGen )
{
//if( eTexCoordGen == m_eTexGen )
// return;
SetActiveTextureUnit( m_uiID );
m_eTexGen = eTexCoordGen;
switch( m_eTexGen )
{
case NeoEngine::TextureLayer::REFLECTION:
{
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
glEnable( GL_TEXTURE_GEN_S );
glEnable( GL_TEXTURE_GEN_T );
glEnable( GL_TEXTURE_GEN_R );
return;
}
case NeoEngine::TextureLayer::NORMAL:
{
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB );
glEnable( GL_TEXTURE_GEN_S );
glEnable( GL_TEXTURE_GEN_T );
glEnable( GL_TEXTURE_GEN_R );
return;
}
default:
case NeoEngine::TextureLayer::NOGEN:
{
glDisable( GL_TEXTURE_GEN_S );
glDisable( GL_TEXTURE_GEN_T );
glDisable( GL_TEXTURE_GEN_R );
return;
}
}
}
/**
* Disable unit
* \return true if unit was enabled, false if not
*/
inline bool Disable()
{
if( m_pkTexture && m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_bEnabled )
{
SetActiveTextureUnit( m_uiID );
glDisable( m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_eTarget );
m_akTarget[ m_pkTexture->m_uiTargetIndex ].m_bEnabled = false;
return true;
}
return false;
}
/**
* Set active texture unit
* \param uiUnit Unit ID
*/
inline static void SetActiveTextureUnit( unsigned int uiUnit )
{
if( uiUnit != s_uiCurUnit )
{
//Safe to use extensions, because in non-multitexturing environments this code
//is unreachable (current unit will always be 0)
neoglActiveTextureARB( GLenum( GL_TEXTURE0_ARB + uiUnit ) );
neoglClientActiveTextureARB( GLenum( GL_TEXTURE0_ARB + uiUnit ) );
s_uiCurUnit = uiUnit;
}
}
};
/**
* \brief Texture unit management for cards with GL_[ARB|EXT]_texture_env_combine support
* \author Mattias Jansson (mattias@realityrift.com)
*/
class TextureUnitCombine : public TextureUnit
{
public:
/**
* \param pkDevice Parent device object
* \param uiID Unit number
*/
TextureUnitCombine( Device *pkDevice, unsigned int uiID ) : TextureUnit( pkDevice, uiID ) {}
/**
*/
virtual ~TextureUnitCombine() {}
/**
* Set blend mode
* \param uiSrcMode Source mode
* \param uiDstMode Destination mode
* \param fFactor Factor
* \return true if compatible mode, false if incompatible
*/
virtual bool SetBlendMode( unsigned int uiSrcMode, unsigned int uiDstMode, float fFactor );
};
}; // namespace NeoOGL
#endif
See more files for this project here