// ChildView.cpp : implementation of the CChildView class
//
#include "stdafx.h"
#include "GLViews.h"
#include "ChildView.h"
#include "MainFrm.h"
#include <io.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// C3DObject
IMPLEMENT_DYNCREATE( C3DObject, CObject );
C3DObject::C3DObject(
LPCTSTR sName, // = GL_VIEWS_NONAME
bool bEnabledParentDependency, // = true
bool bEnabledScale, // = false
bool bEnabledTranslation, // = true
bool bEnabledOrientation // = true
)
: m_sName( sName )
, m_pParent( NULL )
, m_bEnabledParentDependency( bEnabledParentDependency )
, m_bEnabledScale( bEnabledScale )
, m_bEnabledTranslation( bEnabledTranslation )
, m_bEnabledOrientation( bEnabledOrientation )
, m_hti( NULL )
{
ASSERT( sName != NULL );
ASSERT( !m_sName.IsEmpty() );
LocalLoadIdentity();
}
C3DObject::~C3DObject()
{
ASSERT( m_pParent == NULL );
for( POSITION pos = m_listChilds.GetHeadPosition();
pos != NULL;
)
{ // walk all childs
C3DObject * pChild = m_listChilds.GetNext( pos );
ASSERT_VALID( pChild );
ASSERT( pChild->m_pParent == this );
pChild->m_pParent = NULL;
delete pChild;
} // walk all childs
m_listChilds.RemoveAll();
}
void C3DObject::SerializeState(
CArchive & ar
)
{
ASSERT_VALID( this );
if( ar.IsStoring() )
{
ar << m_v3LocalScale.x;
ar << m_v3LocalScale.y;
ar << m_v3LocalScale.z;
ar << m_v3LocalTranslation.x;
ar << m_v3LocalTranslation.y;
ar << m_v3LocalTranslation.z;
ar << m_quatLocalOrientation.x;
ar << m_quatLocalOrientation.y;
ar << m_quatLocalOrientation.z;
ar << m_quatLocalOrientation.w;
// ar << m_mtxLastTransformation.m11;
// ar << m_mtxLastTransformation.m21;
// ar << m_mtxLastTransformation.m31;
// ar << m_mtxLastTransformation.m41;
// ar << m_mtxLastTransformation.m12;
// ar << m_mtxLastTransformation.m22;
// ar << m_mtxLastTransformation.m32;
// ar << m_mtxLastTransformation.m42;
// ar << m_mtxLastTransformation.m13;
// ar << m_mtxLastTransformation.m23;
// ar << m_mtxLastTransformation.m33;
// ar << m_mtxLastTransformation.m43;
// ar << m_mtxLastTransformation.m14;
// ar << m_mtxLastTransformation.m24;
// ar << m_mtxLastTransformation.m34;
// ar << m_mtxLastTransformation.m44;
ar << m_sName;
DWORD dwEnabledFlags = 0L;
if( m_bEnabledParentDependency )
dwEnabledFlags |= 0x00000001L;
if( m_bEnabledScale )
dwEnabledFlags |= 0x00000002L;
if( m_bEnabledTranslation )
dwEnabledFlags |= 0x00000004L;
if( m_bEnabledOrientation )
dwEnabledFlags |= 0x00000008L;
ar << dwEnabledFlags;
} // if( ar.IsStoring() )
else
{
LocalLoadIdentity();
ar >> m_v3LocalScale.x;
ar >> m_v3LocalScale.y;
ar >> m_v3LocalScale.z;
ar >> m_v3LocalTranslation.x;
ar >> m_v3LocalTranslation.y;
ar >> m_v3LocalTranslation.z;
ar >> m_quatLocalOrientation.x;
ar >> m_quatLocalOrientation.y;
ar >> m_quatLocalOrientation.z;
ar >> m_quatLocalOrientation.w;
// ar >> m_mtxLastTransformation.m11;
// ar >> m_mtxLastTransformation.m21;
// ar >> m_mtxLastTransformation.m31;
// ar >> m_mtxLastTransformation.m41;
// ar >> m_mtxLastTransformation.m12;
// ar >> m_mtxLastTransformation.m22;
// ar >> m_mtxLastTransformation.m32;
// ar >> m_mtxLastTransformation.m42;
// ar >> m_mtxLastTransformation.m13;
// ar >> m_mtxLastTransformation.m23;
// ar >> m_mtxLastTransformation.m33;
// ar >> m_mtxLastTransformation.m43;
// ar >> m_mtxLastTransformation.m14;
// ar >> m_mtxLastTransformation.m24;
// ar >> m_mtxLastTransformation.m34;
// ar >> m_mtxLastTransformation.m44;
ar >> m_sName;
ASSERT( !m_sName.IsEmpty() );
m_bEnabledParentDependency = false;
m_bEnabledScale = false;
m_bEnabledTranslation = false;
m_bEnabledOrientation = false;
DWORD dwEnabledFlags = 0L;
ar >> dwEnabledFlags;
if( (dwEnabledFlags&0x00000001L) != 0 )
m_bEnabledParentDependency = true;
if( (dwEnabledFlags&0x00000002L) != 0 )
m_bEnabledScale = true;
if( (dwEnabledFlags&0x00000004L) != 0 )
m_bEnabledTranslation = true;
if( (dwEnabledFlags&0x00000008L) != 0 )
m_bEnabledOrientation = true;
} // else from if( ar.IsStoring() )
}
void C3DObject::WalkTree(
C3DObject::eWalkTreeQuery walkTreeQuery,
C3DCamera * pCam,
C3DView * pView3D,
LPVOID lpvCookie,
C3DMirror * pObjMirror // = NULL
)
{
ASSERT_VALID( this );
if( !OnWalkTree(
walkTreeQuery,
pCam,
pView3D,
lpvCookie,
pObjMirror
)
)
return;
for( POSITION pos = m_listChilds.GetHeadPosition();
pos != NULL;
)
{ // walk all childs
C3DObject * pChild = m_listChilds.GetNext( pos );
ASSERT_VALID( pChild );
ASSERT( pChild->m_pParent == this );
if( walkTreeQuery == EWTQ_RENDER
&& ( !IsRenderSubtreeItem(pChild) )
)
continue;
pChild->WalkTree(
walkTreeQuery,
pCam,
pView3D,
lpvCookie,
pObjMirror
);
} // walk all childs
}
bool C3DObject::OnWalkTree(
C3DObject::eWalkTreeQuery walkTreeQuery,
C3DCamera * pCam,
C3DView * pView3D,
LPVOID lpvCookie,
C3DMirror * pObjMirror
)
{
bool bRetVal = true;
ASSERT_VALID( this );
switch( walkTreeQuery )
{
case EWTQ_THREAD_INIT:
OnThreadInit( lpvCookie );
break;
case EWTQ_THREAD_DONE:
OnThreadDone( lpvCookie );
break;
case EWTQ_PLAY:
OnPlay( lpvCookie );
break;
case EWTQ_TRANSFORM:
ASSERT_VALID( pCam );
ASSERT_VALID( pView3D );
OnTransform( pCam, pView3D, lpvCookie );
break;
case EWTQ_RENDER:
ASSERT_VALID( pCam );
ASSERT_VALID( pView3D );
OnRender( pCam, pView3D, lpvCookie, pObjMirror );
if( !IsRenderSubtree() )
bRetVal = false;
break;
case EWTQ_ADD_TO_TREE:
OnAddToTree( (CObjectHierarchyTreeCtrl*)lpvCookie );
break;
} // switch( walkTreeQuery )
return bRetVal;
}
void C3DObject::OnThreadInit( LPVOID lpvCookie )
{
ASSERT_VALID( this );
lpvCookie;
}
void C3DObject::OnThreadDone( LPVOID lpvCookie )
{
ASSERT_VALID( this );
lpvCookie;
}
void C3DObject::OnPlay(
LPVOID lpvCookie
)
{
ASSERT_VALID( this );
lpvCookie;
}
void C3DObject::CalcTransformation(
_mrct mtxParentTransformation
)
{
ASSERT_VALID( this );
if( m_bEnabledParentDependency )
m_mtxLastTransformation = mtxParentTransformation;
else
m_mtxLastTransformation.load_identity();
if( m_bEnabledScale )
m_mtxLastTransformation *= m_v3LocalScale.get_as_scale();
if( m_bEnabledTranslation )
m_mtxLastTransformation *= m_v3LocalTranslation.get_as_translation();
if( m_bEnabledOrientation )
m_mtxLastTransformation *= m_quatLocalOrientation;
}
void C3DObject::OnTransform(
C3DCamera * pCam,
C3DView * pView3D,
LPVOID lpvCookie
)
{
ASSERT_VALID( this );
ASSERT_VALID( pCam );
ASSERT_VALID( pView3D );
pCam;
pView3D;
lpvCookie;
C3DObject * pParent = GetParent();
if( pParent != NULL )
CalcTransformation( pParent->m_mtxLastTransformation );
else
{
_mt mtxIdentity;
CalcTransformation( mtxIdentity );
}
}
void C3DObject::OnRender(
C3DCamera * pCam,
C3DView * pView3D,
LPVOID lpvCookie,
C3DMirror * pObjMirror
)
{
ASSERT_VALID( this );
ASSERT_VALID( pCam );
ASSERT_VALID( pView3D );
pCam;
pView3D;
lpvCookie;
pObjMirror;
}
bool C3DObject::IsRenderSubtree()
{
ASSERT_VALID( this );
return true;
}
bool C3DObject::IsRenderSubtreeItem( C3DObject * pObjChild )
{
ASSERT_VALID( this );
ASSERT_VALID( pObjChild );
ASSERT( pObjChild->GetParent() == this );
pObjChild;
return true;
}
void C3DObject::OnAddToTree(
CObjectHierarchyTreeCtrl * pTreeCtrl
)
{
ASSERT_VALID( this );
ASSERT_VALID( pTreeCtrl );
ASSERT( pTreeCtrl->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( pTreeCtrl->GetSafeHwnd() ) );
ASSERT( m_hti == NULL );
HTREEITEM htiParent = TVI_ROOT;
C3DObject * pObjParent = GetParent();
if( pObjParent != NULL )
{
ASSERT_VALID( pObjParent );
htiParent = pObjParent->m_hti;
ASSERT( htiParent != NULL );
}
CString strTreeItemText;
int nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_GENERIC_OBJ;
OnQueryTreeDisplayParms(
strTreeItemText,
nTreeImageIndex
);
ASSERT( !strTreeItemText.IsEmpty() );
m_hti =
pTreeCtrl->InsertItem(
(LPCTSTR)strTreeItemText,
nTreeImageIndex,
nTreeImageIndex,
htiParent,
TVI_LAST
);
ASSERT( m_hti != NULL );
VERIFY( pTreeCtrl->SetItemData( m_hti, (DWORD)this ) );
}
void C3DObject::OnTreeItemDblClick(
CObjectHierarchyTreeCtrl * pTreeCtrl
)
{
ASSERT_VALID( this );
ASSERT_VALID( pTreeCtrl );
ASSERT( pTreeCtrl->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( pTreeCtrl->GetSafeHwnd() ) );
ASSERT( m_hti != NULL );
pTreeCtrl;
}
void C3DObject::OnQueryTreeDisplayParms(
CString & strTreeItemText,
int & nTreeImageIndex
)
{
ASSERT_VALID( this );
strTreeItemText = GetName();
ASSERT( !strTreeItemText.IsEmpty() );
if( m_pParent == NULL )
nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_ROOT;
}
void C3DObject::GenerateSphere(
int nTextureIndex,
_v3rct ptCenter,
GLfloat fRadius,
int nStacksCount,
GLfloat fAngleTheta0,
GLfloat fAngleTheta1,
GLfloat fAngleTheta1Phi0,
GLfloat fAngleTheta1Phi1,
bool bNoDepth // = false
)
{
ASSERT( fRadius >= 0 && nStacksCount > 3 );
for( int nStackIdx0 = 0; nStackIdx0 < (nStacksCount / 2); nStackIdx0++ )
{
GLfloat fAngleStack0 =
fAngleTheta1Phi0 +
( fAngleTheta1Phi1 - fAngleTheta1Phi0 ) /
( nStacksCount / 2 ) * nStackIdx0 ;
GLfloat fAngleStack1 =
fAngleTheta1Phi0 +
( fAngleTheta1Phi1 - fAngleTheta1Phi0 ) /
( nStacksCount / 2 ) * ( nStackIdx0 + 1 );
_v3t
vNormalPrev0, vNormalCurr0, vNormalPrev1, vNormalCurr1,
vVertexPrev0, vVertexCurr0, vVertexPrev1, vVertexCurr1;
GLfloat
fTextureCoordPrevX0 = 0.0f, fTextureCoordPrevY0 = 0.0f,
fTextureCoordCurrX0 = 0.0f, fTextureCoordCurrY0 = 0.0f,
fTextureCoordPrevX1 = 0.0f, fTextureCoordPrevY1 = 0.0f,
fTextureCoordCurrX1 = 0.0f, fTextureCoordCurrY1 = 0.0f;
for( int nStackIdx1 = 0; nStackIdx1 <= nStacksCount; nStackIdx1++ )
{
if( nStackIdx1 > 0 )
{
vNormalPrev0 = vNormalCurr0;
vNormalPrev1 = vNormalCurr1;
vVertexPrev0 = vVertexCurr0;
vVertexPrev1 = vVertexCurr1;
fTextureCoordPrevX0 = fTextureCoordCurrX0;
fTextureCoordPrevX1 = fTextureCoordCurrX1;
fTextureCoordPrevY0 = fTextureCoordCurrY0;
fTextureCoordPrevY1 = fTextureCoordCurrY1;
} // if( nStackIdx1 > 0 )
GLfloat fAngleStack2 =
fAngleTheta0 +
nStackIdx1 * (fAngleTheta1 - fAngleTheta0)
/ nStacksCount;
vNormalCurr0.load_vector(
_ntr::cos(fAngleStack0) * _ntr::cos(fAngleStack2),
_ntr::sin(fAngleStack0),
_ntr::cos(fAngleStack0) * _ntr::sin(fAngleStack2)
);
vVertexCurr0.load_vector(
ptCenter.x + fRadius * vNormalCurr0.x,
ptCenter.y + fRadius * vNormalCurr0.y,
ptCenter.z + fRadius * vNormalCurr0.z
);
fTextureCoordCurrX0 = ((GLfloat)nStackIdx1) / ((GLfloat)nStacksCount);
fTextureCoordCurrY0 = (2.0f * nStackIdx0) / ((GLfloat)nStacksCount);
vNormalCurr1.load_vector(
_ntr::cos(fAngleStack1) * _ntr::cos(fAngleStack2),
_ntr::sin(fAngleStack1),
_ntr::cos(fAngleStack1) * _ntr::sin(fAngleStack2)
);
vVertexCurr1.load_vector(
ptCenter.x + fRadius * vNormalCurr1.x,
ptCenter.y + fRadius * vNormalCurr1.y,
ptCenter.z + fRadius * vNormalCurr1.z
);
fTextureCoordCurrX1 = ((GLfloat)nStackIdx1) / ((GLfloat)nStacksCount);
fTextureCoordCurrY1 = (2 * (nStackIdx0 + 1)) / (GLfloat)nStacksCount;
if( nStackIdx1 > 0 )
{
C3DSquare * pObjSquare = new C3DSquare;
pObjSquare->m_nTextureIndex = nTextureIndex;
pObjSquare->m_bNoDepth = bNoDepth;
pObjSquare->m_bUseNormal = true;
pObjSquare->m_vecNormal = vNormalCurr1;
pObjSquare->m_arrTextureCoords[0].m_fX = fTextureCoordPrevX0;
pObjSquare->m_arrTextureCoords[0].m_fY = fTextureCoordPrevY0;
pObjSquare->m_arrPoints[0] = vVertexPrev0;
pObjSquare->m_arrTextureCoords[1].m_fX = fTextureCoordPrevX1;
pObjSquare->m_arrTextureCoords[1].m_fY = fTextureCoordPrevY1;
pObjSquare->m_arrPoints[1] = vVertexPrev1;
pObjSquare->m_arrTextureCoords[2].m_fX = fTextureCoordCurrX1;
pObjSquare->m_arrTextureCoords[2].m_fY = fTextureCoordCurrY1;
pObjSquare->m_arrPoints[2] = vVertexCurr1;
pObjSquare->m_arrTextureCoords[3].m_fX = fTextureCoordCurrX0;
pObjSquare->m_arrTextureCoords[3].m_fY = fTextureCoordCurrY0;
pObjSquare->m_arrPoints[3] = vVertexCurr0;
AddChild( pObjSquare );
} // if( nStackIdx1 > 0 )
} // for( int nStackIdx1 = 0; nStackIdx1 <= nStacksCount; nStackIdx1++ )
} // for( int nStackIdx0 = 0; nStackIdx0 < (nStacksCount / 2); nStackIdx0++ )
}
bool C3DObject::stat_LoadResourceToMemory(
LPCTSTR pszResId,
LPCTSTR pszRsType,
LPVOID * pLpvOutBuffer,
DWORD * pDwOutSize
)
{
*pLpvOutBuffer = NULL;
*pDwOutSize = 0L;
HINSTANCE hInst =
::AfxFindResourceHandle( pszResId, pszRsType );
if( hInst == NULL )
{
ASSERT( FALSE );
return false;
}
HRSRC hRsrc = FindResource( hInst, pszResId, pszRsType );
if( hRsrc == NULL )
{
ASSERT( FALSE );
return false;
}
HGLOBAL hGlobal = LoadResource( hInst, hRsrc );
if( hGlobal == NULL )
{
ASSERT( FALSE );
return false;
}
LPVOID lpvData = LockResource( hGlobal );
DWORD dwSize = SizeofResource( hInst, hRsrc );
if( lpvData == NULL )
{
ASSERT( FALSE );
::UnlockResource( hGlobal );
::FreeResource( hGlobal );
return false;
}
if( dwSize == 0L )
{
ASSERT( FALSE );
::UnlockResource( hGlobal );
::FreeResource( hGlobal );
return false;
}
*pLpvOutBuffer = malloc( dwSize );
if( (*pLpvOutBuffer) == NULL )
{
ASSERT( FALSE );
::UnlockResource( hGlobal );
::FreeResource( hGlobal );
return false;
}
memcpy( *pLpvOutBuffer, lpvData, dwSize );
*pDwOutSize = dwSize;
::UnlockResource( hGlobal );
::FreeResource( hGlobal );
return true;
}
bool C3DObject::stat_IsFileExists(
LPCTSTR sFilePath
)
{
ASSERT( sFilePath != NULL );
if( sFilePath == NULL )
return false;
#if (defined _UNICODE)
struct _wfinddata_t fd;
#else
struct _finddata_t fd;
#endif
long hNextFile =
#if (defined _UNICODE)
_wfindfirst(
#else
_findfirst(
#endif
(LPTSTR)sFilePath,
&fd
);
bool bExists = true;
if( hNextFile < 0 )
bExists = false;
else
{
if( (fd.attrib&_A_SUBDIR) != 0 )
bExists = false;
} // else from if( hNextFile < 0 )
_findclose( hNextFile );
return bExists;
}
/////////////////////////////////////////////////////////////////////////////
// C3DModifier
IMPLEMENT_DYNCREATE( C3DModifier, C3DObject );
C3DModifier::C3DModifier(
LPCTSTR sName, // = GL_VIEWS_NONAME
GLfloat fAnglePlayStepPitch, // = 0.0f
GLfloat fAnglePlayStepYaw, // = 0.0f
GLfloat fAnglePlayStepRoll // = 0.0f
)
: C3DObject( sName )
, m_fAnglePlayStepPitch( fAnglePlayStepPitch )
, m_fAnglePlayStepYaw( fAnglePlayStepYaw )
, m_fAnglePlayStepRoll( fAnglePlayStepRoll )
{
}
C3DModifier::~C3DModifier()
{
}
void C3DModifier::OnQueryTreeDisplayParms(
CString & strTreeItemText,
int & nTreeImageIndex
)
{
ASSERT_VALID( this );
ASSERT( !m_sName.IsEmpty() );
int nCount = m_listChilds.GetCount();
ASSERT( nCount > 0 );
if( nCount > 1 )
{
strTreeItemText = _T("Group modifier \"");
strTreeItemText += m_sName;
strTreeItemText += _T("\"");
nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_MODIFIER_GRP;
return;
} // if( nCount > 1 )
C3DObject * pObjHead = m_listChilds.GetHead();
ASSERT_VALID( pObjHead );
CString strChildDisplayText;
pObjHead->OnQueryTreeDisplayParms(
strChildDisplayText,
nTreeImageIndex
);
ASSERT( !strChildDisplayText.IsEmpty() );
strTreeItemText = _T("Modifier for: ");
strTreeItemText += strChildDisplayText;
nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_MODIFIER_ONE;
}
void C3DModifier::OnPlay(
LPVOID lpvCookie
)
{
ASSERT_VALID( this );
lpvCookie;
#ifdef GL_VIEWS_DRAW_ANIMS
if( m_fAnglePlayStepPitch != 0.0f
&& m_fAnglePlayStepYaw != 0.0f
&& m_fAnglePlayStepRoll != 0.0f
)
LocalAdjustOrientation(
m_fAnglePlayStepPitch,
m_fAnglePlayStepYaw,
m_fAnglePlayStepRoll
);
#endif // GL_VIEWS_DRAW_ANIMS
}
/////////////////////////////////////////////////////////////////////////////
// C3DSquare
IMPLEMENT_DYNCREATE( C3DSquare, C3DObject );
C3DSquare::C3DSquare()
: C3DObject( GL_VIEWS_SQUARE_NAME )
, m_nTextureIndex( -1 )
, m_bUseNormal( false )
, m_bNoDepth( false )
, m_bNoCullFace( false )
, m_bAdjustAlphaFunc( false )
, m_bAdjustBlendFunc( false )
, m_gleAlphaFunc( GL_NOTEQUAL )
, m_glcAlphaRef( 0.0f )
, m_gleBlendFactorS( GL_SRC_ALPHA )
, m_gleBlendFactorD( GL_ONE )
{
}
C3DSquare::~C3DSquare()
{
}
void C3DSquare::OnRender(
C3DCamera * pCam,
C3DView * pView3D,
LPVOID lpvCookie,
C3DMirror * pObjMirror
)
{
ASSERT_VALID( this );
ASSERT_VALID( pCam );
ASSERT_VALID( pView3D );
pCam;
pView3D;
lpvCookie;
pObjMirror;
glPushMatrix();
glMultMatrixf( m_mtxLastTransformation.arr );
if( m_bNoDepth )
{
glDisable( GL_DEPTH_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
} // if( m_bNoDepth )
if( m_bNoCullFace )
{
glDisable( GL_CULL_FACE );
GL_VIEWS_CHECK_OPENGL_ERROR
} // if( m_bNoCullFace )
if( m_bAdjustAlphaFunc )
{
glEnable( GL_ALPHA_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glAlphaFunc( m_gleAlphaFunc, m_glcAlphaRef );
GL_VIEWS_CHECK_OPENGL_ERROR
} // if( m_bAdjustAlphaFunc )
if( m_bAdjustBlendFunc )
{
glEnable( GL_BLEND );
GL_VIEWS_CHECK_OPENGL_ERROR
glBlendFunc( m_gleBlendFactorS, m_gleBlendFactorD );
GL_VIEWS_CHECK_OPENGL_ERROR
} // if( m_bAdjustBlendFunc )
if( m_nTextureIndex >= 0 )
{
ASSERT( m_nTextureIndex < GL_VIEWS_TEXTURE_COUNT );
glEnable( GL_TEXTURE_2D );
GL_VIEWS_CHECK_OPENGL_ERROR
glBindTexture(
GL_TEXTURE_2D,
pView3D->m_TextureIds[m_nTextureIndex]
);
GL_VIEWS_CHECK_OPENGL_ERROR
} // if( m_nTextureIndex >= 0 )
glBegin(GL_QUADS);
for( int nVertexIdx = 0; nVertexIdx < 4; nVertexIdx++ )
{
glTexCoord2f(
m_arrTextureCoords[nVertexIdx].m_fX,
m_arrTextureCoords[nVertexIdx].m_fY
);
glVertex3fv(
m_arrPoints[nVertexIdx].arr
);
}
glEnd();
if( m_nTextureIndex >= 0 )
{
ASSERT( m_nTextureIndex < GL_VIEWS_TEXTURE_COUNT );
glDisable( GL_TEXTURE_2D );
GL_VIEWS_CHECK_OPENGL_ERROR
} // if( m_nTextureIndex >= 0 )
if( m_bAdjustBlendFunc )
{
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
GL_VIEWS_CHECK_OPENGL_ERROR
glDisable( GL_BLEND );
GL_VIEWS_CHECK_OPENGL_ERROR
} // if( m_bAdjustBlendFunc )
if( m_bAdjustAlphaFunc )
{
glDisable( GL_ALPHA_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
} // if( m_bAdjustAlphaFunc )
if( m_bNoCullFace )
{
glEnable( GL_CULL_FACE );
GL_VIEWS_CHECK_OPENGL_ERROR
} // if( m_bNoCullFace )
if( m_bNoDepth )
{
glEnable( GL_DEPTH_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
} // if( m_bNoDepth )
glPopMatrix();
}
/////////////////////////////////////////////////////////////////////////////
// C3DOuterScene
IMPLEMENT_DYNCREATE( C3DOuterScene, C3DObject );
volatile bool C3DOuterScene::g_bRenderOuterScene = true;
GLfloat C3DOuterScene::g_fBottomPlaneValX = 0.7f;
GLfloat C3DOuterScene::g_fBottomPlaneValY = 0.4f;
GLfloat C3DOuterScene::g_fBottomPlaneValZ = 0.7f;
GLfloat C3DOuterScene::g_fRingRadius = 0.80f;
GLint C3DOuterScene::g_nSphereValStacks = 12;
C3DOuterScene::C3DOuterScene()
: C3DObject( GL_VIEWS_OUTER_SCENE_NAME )
{
}
C3DOuterScene::~C3DOuterScene()
{
}
void C3DOuterScene::OnThreadInit( LPVOID lpvCookie )
{
ASSERT_VALID( this );
lpvCookie;
C3DSquare * pObjSquare = new C3DSquare;
pObjSquare->m_nTextureIndex = GL_VIEWS_TEXTURE_IDX_BOTTOM_PLANE;
pObjSquare->m_bNoDepth = true;
pObjSquare->m_arrTextureCoords[3].m_fX = 2.0f;
pObjSquare->m_arrTextureCoords[3].m_fY = 2.0f;
pObjSquare->m_arrPoints[3] = _v3t( -g_fBottomPlaneValX, -g_fBottomPlaneValY, -g_fBottomPlaneValZ );
pObjSquare->m_arrTextureCoords[2].m_fX = 0.0f;
pObjSquare->m_arrTextureCoords[2].m_fY = 2.0f;
pObjSquare->m_arrPoints[2] = _v3t( g_fBottomPlaneValX, -g_fBottomPlaneValY, -g_fBottomPlaneValZ );
pObjSquare->m_arrTextureCoords[1].m_fX = 0.0f;
pObjSquare->m_arrTextureCoords[1].m_fY = 0.0f;
pObjSquare->m_arrPoints[1] = _v3t( g_fBottomPlaneValX, -g_fBottomPlaneValY, g_fBottomPlaneValZ );
pObjSquare->m_arrTextureCoords[0].m_fX = 2.0f;
pObjSquare->m_arrTextureCoords[0].m_fY = 0.0f;
pObjSquare->m_arrPoints[0] = _v3t( -g_fBottomPlaneValX, -g_fBottomPlaneValY, g_fBottomPlaneValZ );
pObjSquare->m_bUseNormal = true;
_v3t pt0(
pObjSquare->m_arrPoints[1].x - pObjSquare->m_arrPoints[0].x,
pObjSquare->m_arrPoints[1].y - pObjSquare->m_arrPoints[0].y,
pObjSquare->m_arrPoints[1].z - pObjSquare->m_arrPoints[0].z
);
_v3t pt1(
pObjSquare->m_arrPoints[2].x - pObjSquare->m_arrPoints[0].x,
pObjSquare->m_arrPoints[2].y - pObjSquare->m_arrPoints[0].y,
pObjSquare->m_arrPoints[2].z - pObjSquare->m_arrPoints[0].z
);
_v3t vNormal = pt0 ^ pt1;
vNormal.normalize();
pObjSquare->m_vecNormal = vNormal;
AddChild( pObjSquare );
GenerateSphere(
GL_VIEWS_TEXTURE_IDX_RING,
_v3t( 0.0f, 0.0f, 0.0f ),
g_fRingRadius,
g_nSphereValStacks,
_ntr::get_pi()*2.0f,
0.0f,
- 0.3f,
+ 0.7f,
true
);
}
bool C3DOuterScene::IsRenderSubtree()
{
ASSERT_VALID( this );
return g_bRenderOuterScene;
}
void C3DOuterScene::OnQueryTreeDisplayParms(
CString & strTreeItemText,
int & nTreeImageIndex
)
{
ASSERT_VALID( this );
C3DObject::OnQueryTreeDisplayParms(
strTreeItemText,
nTreeImageIndex
);
nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_OUTER_SCENE;
}
/////////////////////////////////////////////////////////////////////////////
// C3DCamera
IMPLEMENT_DYNCREATE( C3DCamera, C3DObject );
const GLfloat C3DCamera::g_arrFovValues[GL_VIEWS_FOV_COUNT] =
{
(( 10.0f*3.1415926535897932384626433832795f)/180.0f ), // 0 10 degrees
(( 15.0f*3.1415926535897932384626433832795f)/180.0f ), // 1 15 degrees
(( 20.0f*3.1415926535897932384626433832795f)/180.0f ), // 2 20 degrees
(( 25.0f*3.1415926535897932384626433832795f)/180.0f ), // 3 25 degrees
(( 30.0f*3.1415926535897932384626433832795f)/180.0f ), // 4 30 degrees
(( 35.0f*3.1415926535897932384626433832795f)/180.0f ), // 5 35 degrees
(( 40.0f*3.1415926535897932384626433832795f)/180.0f ), // 6 40 degrees
(( 45.0f*3.1415926535897932384626433832795f)/180.0f ), // 7 45 degrees
(( 50.0f*3.1415926535897932384626433832795f)/180.0f ), // 8 50 degrees
(( 55.0f*3.1415926535897932384626433832795f)/180.0f ), // 9 55 degrees
(( 60.0f*3.1415926535897932384626433832795f)/180.0f ), // 10 60 degrees
(( 65.0f*3.1415926535897932384626433832795f)/180.0f ), // 11 65 degrees
(( 70.0f*3.1415926535897932384626433832795f)/180.0f ), // 12 70 degrees
(( 75.0f*3.1415926535897932384626433832795f)/180.0f ), // 13 75 degrees
(( 80.0f*3.1415926535897932384626433832795f)/180.0f ), // 14 80 degrees
(( 85.0f*3.1415926535897932384626433832795f)/180.0f ), // 15 85 degrees
(( 90.0f*3.1415926535897932384626433832795f)/180.0f ), // 16 90 degrees
(( 95.0f*3.1415926535897932384626433832795f)/180.0f ), // 17 95 degrees
((100.0f*3.1415926535897932384626433832795f)/180.0f ), // 18 100 degrees
((110.0f*3.1415926535897932384626433832795f)/180.0f ), // 19 110 degrees
((120.0f*3.1415926535897932384626433832795f)/180.0f ), // 20 120 degrees
((130.0f*3.1415926535897932384626433832795f)/180.0f ), // 21 130 degrees
((140.0f*3.1415926535897932384626433832795f)/180.0f ), // 22 140 degrees
((150.0f*3.1415926535897932384626433832795f)/180.0f ), // 23 150 degrees
((160.0f*3.1415926535897932384626433832795f)/180.0f ), // 24 160 degrees
((170.0f*3.1415926535897932384626433832795f)/180.0f ), // 25 170 degrees
};
volatile bool C3DCamera::g_bRenderCameraAxes = true;
GLfloat C3DCamera::g_fAxisLineLength = 0.025f;
GLfloat C3DCamera::g_fAxisLineWidth = 2.0f;
C3DCamera::C3DCamera(
UINT nTreeDblClickCmdID, // = 0L
LPCTSTR sName, // = GL_VIEWS_NONAME
int nFovIndex, // = GL_VIEWS_FOV_DEF_INDEX
GLfloat fNearPlane, // = 1.0f
GLfloat fFarPlane // = 5.0f
)
: C3DObject( sName )
, m_nTreeDblClickCmdID( nTreeDblClickCmdID )
, m_fAspect( 1.0f )
, m_nFovIndex( nFovIndex )
, m_fNearPlane( fNearPlane )
, m_fFarPlane( fFarPlane )
{
ASSERT( 0 <= m_nFovIndex && m_nFovIndex < GL_VIEWS_FOV_COUNT );
}
C3DCamera::~C3DCamera()
{
}
void C3DCamera::SerializeState(
CArchive & ar
)
{
ASSERT_VALID( this );
ASSERT( 0 <= m_nFovIndex && m_nFovIndex < GL_VIEWS_FOV_COUNT );
C3DObject::SerializeState( ar );
if( ar.IsStoring() )
{
ar << m_fAspect;
ar << m_nFovIndex;
ar << m_fNearPlane;
ar << m_fFarPlane;
} // if( ar.IsStoring() )
else
{
ar >> m_fAspect;
ar >> m_nFovIndex;
ASSERT( 0 <= m_nFovIndex && m_nFovIndex < GL_VIEWS_FOV_COUNT );
if( !(0 <= m_nFovIndex && m_nFovIndex < GL_VIEWS_FOV_COUNT) )
m_nFovIndex = GL_VIEWS_FOV_DEF_INDEX;
ar >> m_fNearPlane;
ar >> m_fFarPlane;
} // else from if( ar.IsStoring() )
}
void C3DCamera::OnRender(
C3DCamera * pCam,
C3DView * pView3D,
LPVOID lpvCookie,
C3DMirror * pObjMirror
)
{
ASSERT_VALID( this );
ASSERT_VALID( pCam );
ASSERT_VALID( pView3D );
pCam;
pView3D;
lpvCookie;
if( (!g_bRenderCameraAxes) )
return;
if( pCam == this && pObjMirror == NULL )
return;
glPushMatrix();
glMultMatrixf( m_mtxLastTransformation.arr );
glLineWidth( g_fAxisLineWidth );
GL_VIEWS_CHECK_OPENGL_ERROR
glBegin( GL_LINES );
glColor3f( 1.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( g_fAxisLineLength, 0.0f, 0.0f );
glColor3f( 0.0f, 1.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, g_fAxisLineLength, 0.0f );
glColor3f( 0.0f, 0.0f, 1.0f ); glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, g_fAxisLineLength );
glColor3f( 1.0f, 1.0f, 1.0f );
glEnd();
glPopMatrix();
}
void C3DCamera::OnTreeItemDblClick(
CObjectHierarchyTreeCtrl * pTreeCtrl
)
{
ASSERT_VALID( this );
ASSERT_VALID( pTreeCtrl );
ASSERT( pTreeCtrl->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( pTreeCtrl->GetSafeHwnd() ) );
ASSERT( m_hti != NULL );
if( m_nTreeDblClickCmdID == 0L )
return;
CFrameWnd * pFrame = pTreeCtrl->GetParentFrame();
ASSERT_VALID( pFrame );
if( pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
{
pFrame = pFrame->GetParentFrame();
ASSERT_VALID( pFrame );
ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
}
pFrame->SendMessage( WM_COMMAND, m_nTreeDblClickCmdID );
}
void C3DCamera::OnQueryTreeDisplayParms(
CString & strTreeItemText,
int & nTreeImageIndex
)
{
ASSERT_VALID( this );
C3DObject::OnQueryTreeDisplayParms(
strTreeItemText,
nTreeImageIndex
);
nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_CAMERA_OBJ;
}
/////////////////////////////////////////////////////////////////////////////
// C3DCube
IMPLEMENT_DYNCREATE( C3DCube, C3DObject );
volatile bool C3DCube::g_bRenderCubeObjects = true;
GLfloat C3DCube::g_fCubeVal = 0.03f;
GLfloat C3DCube::g_fTranslateCubeVal = C3DCube::g_fCubeVal * 2.2f;
C3DCube::C3DCube(
LPCTSTR sName, // = GL_VIEWS_NONAME
bool bCenterCube // = false
)
: C3DObject( sName )
, m_bCenterCube( bCenterCube )
{
}
C3DCube::~C3DCube()
{
}
GLfloat C3DCube::g_fCenterCubePlayPitch = _ntr::d2r(0.4f);
GLfloat C3DCube::g_fCenterCubePlayYaw = _ntr::d2r(0.3f);
GLfloat C3DCube::g_fCenterCubePlayRoll = _ntr::d2r(0.2f);
void C3DCube::OnThreadInit( LPVOID lpvCookie )
{
ASSERT_VALID( this );
lpvCookie;
static const struct
{
int m_nTextureIndex;
struct {
GLfloat m_fTextureX, m_fTextureY,
m_fPosX, m_fPosY, m_fPosZ;
} m_arrVertexData[4];
} g_arrSquaresInitData[] =
{
{ GL_VIEWS_TEXTURE_IDX_CUBE_WHITE,
{
{ 0.0f, 0.0f, -g_fCubeVal, -g_fCubeVal, g_fCubeVal },
{ 1.0f, 0.0f, g_fCubeVal, -g_fCubeVal, g_fCubeVal },
{ 1.0f, 1.0f, g_fCubeVal, g_fCubeVal, g_fCubeVal },
{ 0.0f, 1.0f, -g_fCubeVal, g_fCubeVal, g_fCubeVal },
},
},
{ GL_VIEWS_TEXTURE_IDX_CUBE_WHITE,
{
{ 1.0f, 0.0f, -g_fCubeVal, -g_fCubeVal, -g_fCubeVal },
{ 1.0f, 1.0f, -g_fCubeVal, g_fCubeVal, -g_fCubeVal },
{ 0.0f, 1.0f, g_fCubeVal, g_fCubeVal, -g_fCubeVal },
{ 0.0f, 0.0f, g_fCubeVal, -g_fCubeVal, -g_fCubeVal },
},
},
{ GL_VIEWS_TEXTURE_IDX_CUBE_ORANGE,
{
{ 1.0f, 0.0f, g_fCubeVal, -g_fCubeVal, -g_fCubeVal },
{ 1.0f, 1.0f, g_fCubeVal, g_fCubeVal, -g_fCubeVal },
{ 0.0f, 1.0f, g_fCubeVal, g_fCubeVal, g_fCubeVal },
{ 0.0f, 0.0f, g_fCubeVal, -g_fCubeVal, g_fCubeVal },
},
},
{ GL_VIEWS_TEXTURE_IDX_CUBE_ORANGE,
{
{ 0.0f, 0.0f, -g_fCubeVal, -g_fCubeVal, -g_fCubeVal },
{ 1.0f, 0.0f, -g_fCubeVal, -g_fCubeVal, g_fCubeVal },
{ 1.0f, 1.0f, -g_fCubeVal, g_fCubeVal, g_fCubeVal },
{ 0.0f, 1.0f, -g_fCubeVal, g_fCubeVal, -g_fCubeVal },
},
},
};
for( int nSquareIdx = 0;
nSquareIdx < (sizeof(g_arrSquaresInitData)/sizeof(g_arrSquaresInitData[0]));
nSquareIdx++
)
{
C3DSquare * pObjSquare = new C3DSquare;
pObjSquare->m_nTextureIndex =
g_arrSquaresInitData[nSquareIdx].m_nTextureIndex;
for( int nVertexIdx = 0; nVertexIdx < 4; nVertexIdx++ )
{
pObjSquare->m_arrTextureCoords[nVertexIdx].m_fX =
g_arrSquaresInitData[nSquareIdx].m_arrVertexData[nVertexIdx].m_fTextureX;
pObjSquare->m_arrTextureCoords[nVertexIdx].m_fY =
g_arrSquaresInitData[nSquareIdx].m_arrVertexData[nVertexIdx].m_fTextureY;
pObjSquare->m_arrPoints[nVertexIdx].x =
g_arrSquaresInitData[nSquareIdx].m_arrVertexData[nVertexIdx].m_fPosX;
pObjSquare->m_arrPoints[nVertexIdx].y =
g_arrSquaresInitData[nSquareIdx].m_arrVertexData[nVertexIdx].m_fPosY;
pObjSquare->m_arrPoints[nVertexIdx].z =
g_arrSquaresInitData[nSquareIdx].m_arrVertexData[nVertexIdx].m_fPosZ;
}
pObjSquare->m_bNoCullFace = true;
pObjSquare->m_bAdjustAlphaFunc = true;
pObjSquare->m_bAdjustBlendFunc = true;
AddChild( pObjSquare );
}
}
void C3DCube::OnPlay(
LPVOID lpvCookie
)
{
ASSERT_VALID( this );
lpvCookie;
#ifdef GL_VIEWS_DRAW_ANIMS
if( m_bCenterCube )
{
ASSERT_VALID( m_pParent );
ASSERT_KINDOF( C3DModifier, m_pParent );
m_pParent->LocalAdjustOrientation(
g_fCenterCubePlayPitch,
g_fCenterCubePlayYaw,
g_fCenterCubePlayRoll
);
}
#endif // GL_VIEWS_DRAW_ANIMS
}
bool C3DCube::IsRenderSubtreeItem( C3DObject * pObjChild )
{
ASSERT_VALID( this );
ASSERT_VALID( pObjChild );
ASSERT( pObjChild->GetParent() == this );
if( g_bRenderCubeObjects )
return true;
if( pObjChild->IsKindOf(RUNTIME_CLASS(C3DSquare)) )
return false;
return true;
}
void C3DCube::OnQueryTreeDisplayParms(
CString & strTreeItemText,
int & nTreeImageIndex
)
{
ASSERT_VALID( this );
strTreeItemText =
m_bCenterCube
? _T("center cube")
: _T("leaf cube")
;
nTreeImageIndex =
m_bCenterCube
? GL_VIEWS_TREE_IMG_IDX_CUBE_CENTER
: GL_VIEWS_TREE_IMG_IDX_CUBE_LEAF
;
}
/////////////////////////////////////////////////////////////////////////////
// C3DPlanet
IMPLEMENT_DYNCREATE( C3DPlanet, C3DObject );
volatile bool C3DPlanet::g_bRenderPlanetObjects = true;
GLfloat C3DPlanet::g_fPlanetRadiusEarth = 0.04f;
GLfloat C3DPlanet::g_fPlanetRadiusMoon = 0.01f;
GLint C3DPlanet::g_nPlanetSphereStacks = 12;
GLfloat C3DPlanet::g_fAnglePlayStepPitchEarth = _ntr::d2r( 2.5f );
GLfloat C3DPlanet::g_fAnglePlayStepPitchMoon = _ntr::d2r( 4.5f );
GLfloat C3DPlanet::g_fAnglePlayStepYawEarth = _ntr::d2r( 1.5f );
GLfloat C3DPlanet::g_fAnglePlayStepYawMoon = _ntr::d2r( 2.5f );
GLfloat C3DPlanet::g_fAnglePlayStepRollEarth = _ntr::d2r( 4.0f );
GLfloat C3DPlanet::g_fAnglePlayStepRollMoon = _ntr::d2r( 6.0f );
C3DPlanet::C3DPlanet(
LPCTSTR sName, // = GL_VIEWS_NONAME
int nPlanetTextureIndex, // = GL_VIEWS_TEXTURE_IDX_EARTH
GLint nPlanetStacks, // = C3DPlanet::g_nPlanetSphereStacks
GLfloat fPlanetRadius, // = C3DPlanet::g_fPlanetRadiusEarth
GLfloat fAnglePlayStepPitch, // = C3DPlanet::g_fAnglePlayStepPitchEarth
GLfloat fAnglePlayStepYaw, // = C3DPlanet::g_fAnglePlayStepYawEarth
GLfloat fAnglePlayStepRoll // = C3DPlanet::g_fAnglePlayStepRollMoon
)
: C3DObject( sName )
, m_nPlanetTextureIndex( nPlanetTextureIndex )
, m_nPlanetStacks( nPlanetStacks )
, m_fPlanetRadius( fPlanetRadius )
, m_fAnglePlayStepPitch( fAnglePlayStepPitch )
, m_fAnglePlayStepYaw( fAnglePlayStepYaw )
, m_fAnglePlayStepRoll( fAnglePlayStepRoll )
{
}
C3DPlanet::~C3DPlanet()
{
}
void C3DPlanet::OnThreadInit( LPVOID lpvCookie )
{
ASSERT_VALID( this );
lpvCookie;
GenerateSphere(
m_nPlanetTextureIndex,
_v3t( 0.0f, 0.0f, 0.0f ),
m_fPlanetRadius,
m_nPlanetStacks,
_ntr::get_pi() * 2.0f,
0.0f,
- _ntr::get_pi() / 2.0f,
+ _ntr::get_pi() / 2.0f
);
}
bool C3DPlanet::IsRenderSubtreeItem( C3DObject * pObjChild )
{
ASSERT_VALID( this );
ASSERT_VALID( pObjChild );
ASSERT( pObjChild->GetParent() == this );
if( g_bRenderPlanetObjects )
return true;
if( pObjChild->IsKindOf(RUNTIME_CLASS(C3DSquare)) )
return false;
return true;
}
void C3DPlanet::OnQueryTreeDisplayParms(
CString & strTreeItemText,
int & nTreeImageIndex
)
{
ASSERT_VALID( this );
C3DObject::OnQueryTreeDisplayParms(
strTreeItemText,
nTreeImageIndex
);
//nTreeImageIndex = ....;
}
void C3DPlanet::OnPlay(
LPVOID lpvCookie
)
{
ASSERT_VALID( this );
lpvCookie;
if( !g_bRenderPlanetObjects )
return;
#ifdef GL_VIEWS_DRAW_ANIMS
ASSERT_VALID( m_pParent );
ASSERT_KINDOF( C3DModifier, m_pParent );
m_pParent->LocalAdjustOrientation(
m_fAnglePlayStepPitch,
m_fAnglePlayStepYaw,
m_fAnglePlayStepRoll
);
#endif // GL_VIEWS_DRAW_ANIMS
}
/////////////////////////////////////////////////////////////////////////////
// C3DText
IMPLEMENT_DYNCREATE( C3DText, C3DObject );
volatile bool C3DText::g_bRenderTextObjects = true;
GLfloat C3DText::g_fScaleModifier = 0.03f;
GLfloat C3DText::g_fAnglePlayStepPitchText = 0.0f;
GLfloat C3DText::g_fAnglePlayStepYawText = 0.0f;
GLfloat C3DText::g_fAnglePlayStepRollText = _ntr::d2r( 2.0f );
C3DText::C3DText(
LPCTSTR sName, // = GL_VIEWS_NONAME // should be used to set displayed text or one letter
COLORREF clrText, // = RGB(255,255,255)
GLfloat fAnglePlayStepPitch, // = C3DText::g_fAnglePlayStepPitchText
GLfloat fAnglePlayStepYaw, // = C3DText::g_fAnglePlayStepYawText
GLfloat fAnglePlayStepRoll // = C3DText::g_fAnglePlayStepRollText
)
: C3DObject( sName )
, m_fRed( GLfloat(GetRValue(clrText)) / 255.0f )
, m_fGreen( GLfloat(GetGValue(clrText)) / 255.0f )
, m_fBlue( GLfloat(GetBValue(clrText)) / 255.0f )
, m_fAnglePlayStepPitch( fAnglePlayStepPitch )
, m_fAnglePlayStepYaw( fAnglePlayStepYaw )
, m_fAnglePlayStepRoll( fAnglePlayStepRoll )
{
}
C3DText::~C3DText()
{
}
void C3DText::OnPlay(
LPVOID lpvCookie
)
{
ASSERT_VALID( this );
lpvCookie;
if( !g_bRenderTextObjects )
return;
#ifdef GL_VIEWS_DRAW_ANIMS
ASSERT_VALID( m_pParent );
ASSERT_KINDOF( C3DModifier, m_pParent );
m_pParent->LocalAdjustOrientation(
m_fAnglePlayStepPitch,
m_fAnglePlayStepYaw,
m_fAnglePlayStepRoll
);
#endif // GL_VIEWS_DRAW_ANIMS
}
void C3DText::OnRender(
C3DCamera * pCam,
C3DView * pView3D,
LPVOID lpvCookie,
C3DMirror * pObjMirror
)
{
ASSERT_VALID( this );
ASSERT_VALID( pCam );
ASSERT_VALID( pView3D );
pCam;
lpvCookie;
pObjMirror;
if( !g_bRenderTextObjects )
return;
if( !pView3D->m_Font3D.IsFontCreated() )
return;
LPCTSTR sText = GetName();
ASSERT( sText != NULL );
if( _tcslen(sText) == 0 )
return;
glEnable( GL_ALPHA_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glAlphaFunc( GL_NOTEQUAL, 0.0 );
GL_VIEWS_CHECK_OPENGL_ERROR
glDisable( GL_CULL_FACE );
GL_VIEWS_CHECK_OPENGL_ERROR
glPushMatrix();
glMultMatrixf( m_mtxLastTransformation.arr );
glColor3f( m_fRed, m_fGreen, m_fBlue );
glEnable( GL_BLEND );
GL_VIEWS_CHECK_OPENGL_ERROR
glBlendFunc( GL_SRC_ALPHA, GL_ONE );
GL_VIEWS_CHECK_OPENGL_ERROR
glPushMatrix();
glScalef(
g_fScaleModifier,
g_fScaleModifier,
g_fScaleModifier
);
pView3D->m_Font3D.TextOut( sText );
glPopMatrix();
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
GL_VIEWS_CHECK_OPENGL_ERROR
glDisable( GL_BLEND );
GL_VIEWS_CHECK_OPENGL_ERROR
glColor3f( 1.0f, 1.0f, 1.0f );
glPopMatrix();
glDisable( GL_ALPHA_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glEnable( GL_CULL_FACE );
GL_VIEWS_CHECK_OPENGL_ERROR
}
void C3DText::OnQueryTreeDisplayParms(
CString & strTreeItemText,
int & nTreeImageIndex
)
{
ASSERT_VALID( this );
strTreeItemText.Format(
_T("text \"%s\""),
GetName()
);
ASSERT( !strTreeItemText.IsEmpty() );
nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_TEXT_OBJ;
}
/////////////////////////////////////////////////////////////////////////////
// C3DWnd
IMPLEMENT_DYNCREATE( C3DWnd, C3DObject );
_v3t C3DWnd::g_arrDefPointsWndAviPlayer[4] =
{
_v3t( -0.12f, -0.11f, -0.35f ),
_v3t( 0.12f, -0.11f, -0.35f ),
_v3t( 0.12f, 0.11f, -0.35f ),
_v3t( -0.12f, 0.11f, -0.35f ),
};
_v3t C3DWnd::g_arrDefPointsWndMirror[4] =
{
_v3t( 0.12f, -0.11f, 0.35f ),
_v3t( -0.12f, -0.11f, 0.35f ),
_v3t( -0.12f, 0.11f, 0.35f ),
_v3t( 0.12f, 0.11f, 0.35f ),
};
C3DWnd::C3DWnd(
LPCTSTR sName, // = GL_VIEWS_WND_AVI_PLAYER
int nPlaneTextureIndex, // = GL_VIEWS_TEXTURE_IDX_WND_AVI_PLAYER
_v3rct pt0, // = C3DWnd::g_arrDefPointsWndAviPlayer[0]
_v3rct pt1, // = C3DWnd::g_arrDefPointsWndAviPlayer[1]
_v3rct pt2, // = C3DWnd::g_arrDefPointsWndAviPlayer[2]
_v3rct pt3 // = C3DWnd::g_arrDefPointsWndAviPlayer[3]
)
: C3DObject( sName )
, m_nPlaneTextureIndex( nPlaneTextureIndex )
{
m_arrWndPoints[0] = pt0;
m_arrWndPoints[1] = pt1;
m_arrWndPoints[2] = pt2;
m_arrWndPoints[3] = pt3;
_RecalcNormalAndContentArea();
}
C3DWnd::~C3DWnd()
{
}
void C3DWnd::_RecalcNormalAndContentArea()
{
ASSERT_VALID( this );
_v3t pt0(
m_arrWndPoints[1].x - m_arrWndPoints[0].x,
m_arrWndPoints[1].y - m_arrWndPoints[0].y,
m_arrWndPoints[1].z - m_arrWndPoints[0].z
);
_v3t pt1(
m_arrWndPoints[2].x - m_arrWndPoints[0].x,
m_arrWndPoints[2].y - m_arrWndPoints[0].y,
m_arrWndPoints[2].z - m_arrWndPoints[0].z
);
m_lastNormal = pt0 ^ pt1;
m_lastNormal.normalize();
stat_CalcWindowContentPlane(
m_arrWndPoints,
m_arrContentPoints
);
}
void C3DWnd::stat_CalcWindowContentPlane(
_v3t * arrWndPoints,
_v3t * arrContentPoints
)
{
ASSERT( arrWndPoints != NULL );
ASSERT( arrContentPoints != NULL );
for( int i = 0; i< 4; i++ )
{
// arrContentPoints[i].x = arrWndPoints[i].x * 0.9700f;
// arrContentPoints[i].y = arrWndPoints[i].y * 0.8000f;
// arrContentPoints[i].z = arrWndPoints[i].z - arrWndPoints[i].z * 0.0001f;
arrContentPoints[i].x = arrWndPoints[i].x * 0.9650f;
arrContentPoints[i].y = arrWndPoints[i].y * ( (i < 2 ) ? 0.7850f : 0.7600f );
arrContentPoints[i].z = arrWndPoints[i].z - arrWndPoints[i].z * 0.0001f;
}
}
void C3DWnd::OnRender(
C3DCamera * pCam,
C3DView * pView3D,
LPVOID lpvCookie,
C3DMirror * pObjMirror
)
{
ASSERT_VALID( this );
ASSERT_VALID( pCam );
ASSERT_VALID( pView3D );
pCam;
pView3D;
lpvCookie;
pObjMirror;
glPushMatrix();
glMultMatrixf( m_mtxLastTransformation.arr );
glEnable( GL_ALPHA_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glAlphaFunc( GL_NOTEQUAL, 0.0f );
GL_VIEWS_CHECK_OPENGL_ERROR
glEnable( GL_BLEND );
GL_VIEWS_CHECK_OPENGL_ERROR
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR );
GL_VIEWS_CHECK_OPENGL_ERROR
glEnable( GL_TEXTURE_2D );
GL_VIEWS_CHECK_OPENGL_ERROR
glBindTexture(
GL_TEXTURE_2D,
pView3D->m_TextureIds[m_nPlaneTextureIndex]
);
GL_VIEWS_CHECK_OPENGL_ERROR
glDisable( GL_DEPTH_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glBegin(GL_QUADS);
glNormal3fv( m_lastNormal.arr );
glTexCoord2f(0.0f, 0.0f); glVertex3fv( m_arrWndPoints[0].arr );
glTexCoord2f(1.0f, 0.0f); glVertex3fv( m_arrWndPoints[1].arr );
glTexCoord2f(1.0f, 1.0f); glVertex3fv( m_arrWndPoints[2].arr );
glTexCoord2f(0.0f, 1.0f); glVertex3fv( m_arrWndPoints[3].arr );
glEnd();
glEnable( GL_DEPTH_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glDisable( GL_TEXTURE_2D );
GL_VIEWS_CHECK_OPENGL_ERROR
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
GL_VIEWS_CHECK_OPENGL_ERROR
glDisable( GL_BLEND );
GL_VIEWS_CHECK_OPENGL_ERROR
glDisable( GL_ALPHA_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glPopMatrix();
}
/////////////////////////////////////////////////////////////////////////////
// C3DMirror
IMPLEMENT_DYNCREATE( C3DMirror, C3DWnd );
volatile bool C3DMirror::g_bRenderMirrors = true;
C3DMirror::C3DMirror(
LPCTSTR sName, // = GL_VIEWS_WND_MIRROR
int nPlaneTextureIndex, // = GL_VIEWS_TEXTURE_IDX_WND_MIRROR
_v3rct pt0, // = C3DWnd::g_arrDefPointsWndMirror[0]
_v3rct pt1, // = C3DWnd::g_arrDefPointsWndMirror[1]
_v3rct pt2, // = C3DWnd::g_arrDefPointsWndMirror[2]
_v3rct pt3 // = C3DWnd::g_arrDefPointsWndMirror[3]
)
: C3DWnd( sName, nPlaneTextureIndex, pt0, pt1, pt2, pt3 )
, m_bRenderingThisMirror( false )
{
}
C3DMirror::~C3DMirror()
{
}
void C3DMirror::OnRender(
C3DCamera * pCam,
C3DView * pView3D,
LPVOID lpvCookie,
C3DMirror * pObjMirror
)
{
ASSERT_VALID( this );
ASSERT_VALID( pCam );
ASSERT_VALID( pView3D );
pCam;
pView3D;
lpvCookie;
if( m_bRenderingThisMirror )
return;
C3DWnd::OnRender( pCam, pView3D, lpvCookie, pObjMirror );
if( !g_bRenderMirrors )
return;
if( pObjMirror != NULL )
return; // multiply mirrors currently not supported by this sample
m_bRenderingThisMirror = true;
// clear mirror (make it black)
glDisable( GL_DEPTH_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glPushMatrix();
glMultMatrixf( m_mtxLastTransformation.arr );
glBegin( GL_QUADS );
glColor3f( 0.0f, 0.0f, 0.0f );
glVertex3fv( m_arrContentPoints[0].arr );
glVertex3fv( m_arrContentPoints[1].arr );
glVertex3fv( m_arrContentPoints[2].arr );
glVertex3fv( m_arrContentPoints[3].arr );
glColor3f( 1.0f, 1.0f, 1.0f );
glEnd();
glPopMatrix();
glEnable( GL_DEPTH_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
// create content mask in the stencil buffer
glEnable( GL_STENCIL_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glStencilFunc( GL_ALWAYS, 1, 1 );
GL_VIEWS_CHECK_OPENGL_ERROR
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
GL_VIEWS_CHECK_OPENGL_ERROR
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
GL_VIEWS_CHECK_OPENGL_ERROR
glDisable( GL_DEPTH_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glPushMatrix();
glMultMatrixf( m_mtxLastTransformation.arr );
glBegin( GL_QUADS );
glVertex3fv( m_arrContentPoints[0].arr );
glVertex3fv( m_arrContentPoints[1].arr );
glVertex3fv( m_arrContentPoints[2].arr );
glVertex3fv( m_arrContentPoints[3].arr );
glEnd();
glPopMatrix();
glEnable( GL_DEPTH_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
GL_VIEWS_CHECK_OPENGL_ERROR
// compute reflection matrix and render mirror content
glStencilFunc( GL_EQUAL, 1, 1 );
GL_VIEWS_CHECK_OPENGL_ERROR
glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
GL_VIEWS_CHECK_OPENGL_ERROR
glPushMatrix();
_mt _mtxReflection;
// TODO: calc dynamically m_arrContentPoints[0].z for _ptEq (plane equation)
_v4t _ptEq( m_lastNormal.x, m_lastNormal.y, m_lastNormal.z, m_arrContentPoints[0].z );
//_v4t _ptEq( 0.0f, 0.0f, -1.0f, 0.35f );
_mtxReflection.load_reflection( _ptEq );
glMultMatrixf( _mtxReflection.arr );
double _ptEqDouble[4] = { _ptEq.a, _ptEq.b, _ptEq.c, _ptEq.d };
glClipPlane( GL_CLIP_PLANE0, _ptEqDouble );
GL_VIEWS_CHECK_OPENGL_ERROR
glEnable( GL_CLIP_PLANE0 );
GL_VIEWS_CHECK_OPENGL_ERROR
glCullFace( GL_BACK );
GL_VIEWS_CHECK_OPENGL_ERROR
the3DPipe.GetRoot()->WalkTree(
C3DObject::EWTQ_RENDER,
pCam,
pView3D,
lpvCookie,
this
);
glCullFace( GL_FRONT );
GL_VIEWS_CHECK_OPENGL_ERROR
glDisable( GL_CLIP_PLANE0 );
GL_VIEWS_CHECK_OPENGL_ERROR
glPopMatrix();
glDisable( GL_STENCIL_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
m_bRenderingThisMirror = false;
}
void C3DMirror::OnQueryTreeDisplayParms(
CString & strTreeItemText,
int & nTreeImageIndex
)
{
ASSERT_VALID( this );
C3DObject::OnQueryTreeDisplayParms(
strTreeItemText,
nTreeImageIndex
);
nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_WND_MIRROR;
}
/////////////////////////////////////////////////////////////////////////////
// C3DAviPlayer
IMPLEMENT_DYNCREATE( C3DAviPlayer, C3DWnd );
volatile bool C3DAviPlayer::g_bRenderAviPlayers = true;
static LPCTSTR g_sAviPlayerTempFilePath = _T(".\\AVITEMP.AVI");
C3DAviPlayer::C3DAviPlayer(
LPCTSTR sName, // = GL_VIEWS_WND_AVI_PLAYER
int nPlaneTextureIndex, // = GL_VIEWS_TEXTURE_IDX_WND_AVI_PLAYER
int nSurfaceTextureIndex, // = GL_VIEWS_TEXTURE_IDX_AVI_SURFACE
_v3rct pt0, // = C3DWnd::g_arrDefPointsWndAviPlayer[0]
_v3rct pt1, // = C3DWnd::g_arrDefPointsWndAviPlayer[1]
_v3rct pt2, // = C3DWnd::g_arrDefPointsWndAviPlayer[2]
_v3rct pt3, // = C3DWnd::g_arrDefPointsWndAviPlayer[3]
int nRenderWidth, // = 256
int nRenderHeight // = 256
)
: C3DWnd( sName, nPlaneTextureIndex, pt0, pt1, pt2, pt3 )
, m_bInitComplete( false )
, m_pAviStream( NULL )
, m_pGetFrame( NULL )
, m_nAviWidth( 0 )
, m_nAviHeight( 0 )
, m_nRenderWidth( nRenderWidth )
, m_nRenderHeight( nRenderHeight )
, m_nRenderSize( nRenderWidth*nRenderHeight )
, m_hDrawDib( NULL )
, m_nFrameNumber( 0 )
, m_nFrameCount( 0 )
, m_hDC( NULL )
, m_hBitmap( NULL )
, m_pDibRawData( NULL )
, m_nSurfaceTextureIndex( nSurfaceTextureIndex )
{
ATLASSERT( m_nRenderWidth > 0 );
ATLASSERT( m_nRenderHeight > 0 );
ATLASSERT( m_nRenderSize > 0 );
}
C3DAviPlayer::~C3DAviPlayer()
{
ASSERT( !m_bInitComplete );
}
void C3DAviPlayer::stat_AlertDisplay( LPCTSTR sText )
{
ASSERT( sText != NULL );
::AfxMessageBox( sText, MB_OK|MB_ICONERROR );
}
void C3DAviPlayer::OnThreadInit( LPVOID lpvCookie )
{
ASSERT_VALID( this );
C3DObject::OnThreadInit( lpvCookie );
ATLASSERT( m_nRenderWidth > 0 );
ATLASSERT( m_nRenderHeight > 0 );
ATLASSERT( m_nRenderSize > 0 );
if( !stat_IsFileExists(g_sAviPlayerTempFilePath) )
{
LPVOID lpvBuffer = NULL;
DWORD dwSize = 0;
if( !stat_LoadResourceToMemory(
MAKEINTRESOURCE(IDR_AVIFILE_FOR_PLAYER),
_T("AVI"),
&lpvBuffer,
&dwSize
)
|| lpvBuffer == NULL
|| dwSize == 0
)
{
ASSERT( FALSE );
stat_AlertDisplay( _T("Failed to load AVI resource") );
return;
}
bool bFileSaved = false;
try
{
CFile _file(
g_sAviPlayerTempFilePath,
CFile::modeCreate
|CFile::modeWrite
|CFile::typeBinary
|CFile::shareExclusive
);
_file.Seek( 0, CFile::begin );
_file.Write( lpvBuffer, dwSize );
_file.Close();
bFileSaved = true;
} // try
catch( CException * pXept )
{
pXept->Delete();
ASSERT( FALSE );
} // catch( CException * pXept )
catch( ... )
{
ASSERT( FALSE );
} // catch( ... )
::free( lpvBuffer );
if( !bFileSaved )
{
ASSERT( FALSE );
stat_AlertDisplay( _T("Failed to extract AVI resource") );
return;
}
} // if( !statIsFileExists(sFilePath) )
::AVIFileInit();
if( ::AVIStreamOpenFromFile(
&m_pAviStream,
g_sAviPlayerTempFilePath,
streamtypeVIDEO,
0,
OF_READ,
NULL
) != 0
)
{
ASSERT( FALSE );
stat_AlertDisplay( _T("AVI stream initialization failed") );
return;
}
::AVIStreamInfo(
m_pAviStream,
&m_pAviInfo,
sizeof(m_pAviInfo)
);
m_nAviWidth =
m_pAviInfo.rcFrame.right - m_pAviInfo.rcFrame.left;
m_nAviHeight =
m_pAviInfo.rcFrame.bottom - m_pAviInfo.rcFrame.top;
m_nFrameCount =
::AVIStreamLength( m_pAviStream );
m_hDC =
::CreateCompatibleDC( NULL );
if( m_hDC == NULL )
{
ASSERT( FALSE );
stat_AlertDisplay( _T("Failed to alloc HDC for AVI stream") );
return;
}
::memset( &m_dataBmpInfoHdr, 0, sizeof(BITMAPINFOHEADER) );
m_dataBmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER);
m_dataBmpInfoHdr.biPlanes = 1;
m_dataBmpInfoHdr.biBitCount = 32; //24;
m_dataBmpInfoHdr.biWidth = m_nRenderWidth;
m_dataBmpInfoHdr.biHeight = m_nRenderHeight;
m_dataBmpInfoHdr.biCompression = BI_RGB;
m_hBitmap =
::CreateDIBSection(
m_hDC,
(BITMAPINFO*)( &m_dataBmpInfoHdr ),
DIB_RGB_COLORS,
(void**)(&m_pDibRawData),
NULL,
NULL
);
if( m_hBitmap == NULL )
{
ASSERT( FALSE );
stat_AlertDisplay( _T("Failed to create DIB section") );
return;
}
ATLASSERT( m_pDibRawData != NULL );
::SelectObject( m_hDC, m_hBitmap );
m_pGetFrame =
::AVIStreamGetFrameOpen(
m_pAviStream,
NULL
);
if( m_pGetFrame == NULL )
{
ASSERT( FALSE );
stat_AlertDisplay( _T("AVI frame initialization failed") );
return;
}
m_hDrawDib = ::DrawDibOpen();
if( m_hDrawDib == NULL )
{
ASSERT( FALSE );
stat_AlertDisplay( _T("DrawDibOpen() failed") );
return;
}
m_bInitComplete = true;
}
void C3DAviPlayer::OnThreadDone( LPVOID lpvCookie )
{
ASSERT_VALID( this );
C3DObject::OnThreadDone( lpvCookie );
if( m_hBitmap != NULL )
::DeleteObject( m_hBitmap );
if( m_hDrawDib != NULL )
::DrawDibClose( m_hDrawDib );
if( m_pGetFrame != NULL )
::AVIStreamGetFrameClose( m_pGetFrame );
if( m_pAviStream != NULL )
::AVIStreamRelease( m_pAviStream );
::AVIFileExit();
try
{
CFile::Remove( g_sAviPlayerTempFilePath );
} // try
catch( CException * pXept )
{
pXept->Delete();
ASSERT( FALSE );
} // catch( CException * pXept )
catch( ... )
{
ASSERT( FALSE );
} // catch( ... )
m_bInitComplete = false;
}
void C3DAviPlayer::OnRender(
C3DCamera * pCam,
C3DView * pView3D,
LPVOID lpvCookie,
C3DMirror * pObjMirror
)
{
ASSERT_VALID( this );
ASSERT_VALID( pCam );
ASSERT_VALID( pView3D );
pCam;
pView3D;
lpvCookie;
C3DWnd::OnRender( pCam, pView3D, lpvCookie, pObjMirror );
if( (!g_bRenderAviPlayers) || (!m_bInitComplete) )
return;
glPushMatrix();
glMultMatrixf( m_mtxLastTransformation.arr );
glEnable( GL_TEXTURE_2D );
GL_VIEWS_CHECK_OPENGL_ERROR
glBindTexture(
GL_TEXTURE_2D,
pView3D->m_TextureIds[m_nSurfaceTextureIndex]
);
GL_VIEWS_CHECK_OPENGL_ERROR
////////// begin get AVI frame //////////
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)
::AVIStreamGetFrame(
m_pGetFrame,
m_nFrameNumber
);
unsigned char * pAviFrameRawData = (unsigned char *)
lpbi
+ lpbi->biSize
+ lpbi->biClrUsed * sizeof(RGBQUAD);
::DrawDibDraw(
m_hDrawDib,
m_hDC,
0, 0, m_nRenderWidth, m_nRenderHeight,
lpbi,
pAviFrameRawData,
0, 0, m_nAviWidth, m_nAviHeight,
0
);
unsigned char * pBufferRGBA = m_pDibRawData;
for( int i = 0; i < m_nRenderSize; i++ )
{
unsigned char _byte = *pBufferRGBA;
*pBufferRGBA = *(pBufferRGBA+2);
pBufferRGBA ++;
pBufferRGBA ++;
*pBufferRGBA = _byte;
pBufferRGBA ++;
*pBufferRGBA = 255;
pBufferRGBA ++;
}
glTexSubImage2D(
GL_TEXTURE_2D, 0,
0, 0, m_nRenderWidth, m_nRenderHeight,
GL_RGBA, GL_UNSIGNED_BYTE,
m_pDibRawData
);
GL_VIEWS_CHECK_OPENGL_ERROR
////////// end get AVI frame //////////
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex3fv( m_arrContentPoints[0].arr );
glTexCoord2f( 1.0f, 0.0f ); glVertex3fv( m_arrContentPoints[1].arr );
glTexCoord2f( 1.0f, 1.0f ); glVertex3fv( m_arrContentPoints[2].arr );
glTexCoord2f( 0.0f, 1.0f ); glVertex3fv( m_arrContentPoints[3].arr );
glEnd();
glDisable( GL_TEXTURE_2D );
GL_VIEWS_CHECK_OPENGL_ERROR
glPopMatrix();
}
void C3DAviPlayer::OnQueryTreeDisplayParms(
CString & strTreeItemText,
int & nTreeImageIndex
)
{
ASSERT_VALID( this );
C3DObject::OnQueryTreeDisplayParms(
strTreeItemText,
nTreeImageIndex
);
nTreeImageIndex = GL_VIEWS_TREE_IMG_IDX_WND_AVI;
}
void C3DAviPlayer::OnPlay(
LPVOID lpvCookie
)
{
ASSERT_VALID( this );
lpvCookie;
#ifdef GL_VIEWS_DRAW_ANIMS
if( m_bInitComplete && g_bRenderAviPlayers )
{
m_nFrameNumber ++;
if( m_nFrameNumber >= m_nFrameCount )
m_nFrameNumber = 0;
} // if( m_bInitComplete && g_bRenderAviPlayers )
#endif // GL_VIEWS_DRAW_ANIMS
}
/////////////////////////////////////////////////////////////////////////////
// C3DTexture
void C3DTexture::_Destroy()
{
if( m_sizeTexture.cx == 0 )
{
ASSERT( m_sizeTexture.cy == 0 );
ASSERT( m_pData == NULL );
return;
}
ASSERT( m_sizeTexture.cy != 0 );
ASSERT( m_pData != NULL );
free( m_pData );
m_sizeTexture.cx = m_sizeTexture.cy = 0;
m_pData = NULL;
m_bAlphaLayerExist = false;
}
C3DTexture::C3DTexture()
: m_sizeTexture( 0, 0 )
, m_pData( NULL )
, m_bAlphaLayerExist( false )
{
}
C3DTexture::~C3DTexture()
{
_Destroy();
}
bool C3DTexture::LoadResourceBitmapAs32Bit(
LPCTSTR lpszResource,
unsigned char nAlphaClearVal // = 255
)
{
Empty();
CBitmap _bmp, _dib, *pBmpOldSrc = NULL, *pBmpOldDst = NULL;
if( !_bmp.LoadBitmap(lpszResource) )
{
ASSERT( FALSE );
return false;
}
BITMAP _bmp_info;
_bmp.GetBitmap( &_bmp_info );
if( _bmp_info.bmPlanes != 1
|| _bmp_info.bmWidth <= 0
|| _bmp_info.bmHeight <= 0
)
{
ASSERT( FALSE );
return false;
}
const int nBytesPerPixel = 4;
int nPixelCount = _bmp_info.bmWidth * _bmp_info.bmHeight;
int nBytesCount = nPixelCount * nBytesPerPixel;
CWindowDC dcDesktop( NULL );
CDC dcSrc, dcDst;
if( !dcSrc.CreateCompatibleDC(&dcDesktop)
|| !dcDst.CreateCompatibleDC(&dcDesktop)
)
{
ASSERT( FALSE );
return false;
}
BITMAPINFOHEADER bih;
::memset( (LPVOID)&bih, 0, sizeof(BITMAPINFOHEADER) );
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = _bmp_info.bmWidth;
bih.biHeight = _bmp_info.bmHeight;
bih.biPlanes = 1;
bih.biBitCount = 32; /*_bmp_info.bmBitsPixel*/;
bih.biCompression = BI_RGB;
bih.biSizeImage = nPixelCount;
LPVOID pColorSurface = NULL;
HBITMAP hDIB =
::CreateDIBSection(
dcDesktop.GetSafeHdc(),
(LPBITMAPINFO)&bih,
DIB_RGB_COLORS,
&pColorSurface,
NULL,
NULL
);
if( hDIB == NULL || pColorSurface == NULL )
{
ASSERT( FALSE );
return false;
}
_dib.Attach( hDIB );
pBmpOldSrc = dcSrc.SelectObject( &_bmp );
pBmpOldDst = dcDst.SelectObject( &_dib );
dcDst.BitBlt(
0, 0, _bmp_info.bmWidth, _bmp_info.bmHeight,
&dcSrc,
0, 0,
SRCCOPY
);
dcDst.SelectObject( pBmpOldDst );
dcSrc.SelectObject( pBmpOldSrc );
m_pData = ::malloc( nBytesCount );
if( m_pData == NULL )
{
ASSERT( FALSE );
return false;
}
::memcpy( m_pData, pColorSurface, nBytesCount );
m_sizeTexture.cx = _bmp_info.bmWidth;
m_sizeTexture.cy = _bmp_info.bmHeight;
ASSERT( !m_bAlphaLayerExist );
m_bAlphaLayerExist = true;
unsigned char
_uc0, _uc1, _uc2,
*pData = (unsigned char *)m_pData;
for( int i = 0; i < nPixelCount; i++ )
{
_uc0 = pData[ 4*i + 0 ];
_uc1 = pData[ 4*i + 1 ];
_uc2 = pData[ 4*i + 2 ];
pData[ 4*i + 0 ] = _uc2;
pData[ 4*i + 1 ] = _uc1;
pData[ 4*i + 2 ] = _uc0;
pData[ 4*i + 3 ] = nAlphaClearVal;
}
return true;
}
bool C3DTexture::AddAlphaLayer(
unsigned char nAlphaClearVal // = 255
)
{
if( IsEmpty() || m_bAlphaLayerExist )
return false;
unsigned char * pDataOld = (unsigned char *)m_pData;
ASSERT( pDataOld != NULL );
ASSERT( m_sizeTexture.cx > 0 && m_sizeTexture.cy > 0 );
int nPixelCount = m_sizeTexture.cx * m_sizeTexture.cy;
unsigned char * pDataNew = new unsigned char[4*nPixelCount];
for( int i = 0; i < nPixelCount; i++ )
{
pDataNew[ 4*i + 0 ] = pDataOld[ 3*i + 0 ];
pDataNew[ 4*i + 1 ] = pDataOld[ 3*i + 1 ];
pDataNew[ 4*i + 2 ] = pDataOld[ 3*i + 2 ];
pDataNew[ 4*i + 3 ] = nAlphaClearVal;
}
delete [] pDataOld;
pDataOld = pDataNew;
return true;
}
bool C3DTexture::SetAlphaLayer(
unsigned char nAlphaSetVal // = 255
)
{
if( IsEmpty() || (!m_bAlphaLayerExist) )
return false;
unsigned char * pData = (unsigned char *)m_pData;
ASSERT( pData != NULL );
ASSERT( m_sizeTexture.cx > 0 && m_sizeTexture.cy > 0 );
int nPixelCount = m_sizeTexture.cx * m_sizeTexture.cy;
for( int i = 0; i < nPixelCount; i++ )
pData[ 4*i + 3 ] = nAlphaSetVal;
return true;
}
bool C3DTexture::SetAlphaLayerIf(
unsigned char nAlphaSetVal,
COLORREF clr
)
{
if( IsEmpty() || (!m_bAlphaLayerExist) )
return false;
unsigned char * pData = (unsigned char *)m_pData;
ASSERT( pData != NULL );
ASSERT( m_sizeTexture.cx > 0 && m_sizeTexture.cy > 0 );
int nPixelCount = m_sizeTexture.cx * m_sizeTexture.cy;
unsigned char byteR = GetRValue(clr);
unsigned char byteG = GetGValue(clr);
unsigned char byteB = GetBValue(clr);
for( int i = 0; i < nPixelCount; i++ )
{
if( byteR == pData[ 4*i + 0 ]
&& byteG == pData[ 4*i + 1 ]
&& byteB == pData[ 4*i + 2 ]
)
pData[ 4*i + 3 ] = nAlphaSetVal;
}
return true;
}
bool C3DTexture::SetAlphaLayerNB()
{
if( IsEmpty() || (!m_bAlphaLayerExist) )
return false;
unsigned char * pData = (unsigned char *)m_pData;
ASSERT( pData != NULL );
ASSERT( m_sizeTexture.cx > 0 && m_sizeTexture.cy > 0 );
int nPixelCount = m_sizeTexture.cx * m_sizeTexture.cy;
for( int i = 0; i < nPixelCount; i++ )
{
unsigned char byteR = pData[ 4*i + 0 ];
pData[ 4*i + 3 ] = byteR;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////
// C3DView
IMPLEMENT_DYNCREATE( C3DView, CObject );
C3DView::C3DView(
HWND hWndOutput // = NULL
)
: m_hWndOutput( hWndOutput )
, m_sizeView( GL_VIEWS_MIN_VIEW_DX, GL_VIEWS_MIN_VIEW_DY )
, m_sizeViewNE( GL_VIEWS_MIN_VIEW_DX, GL_VIEWS_MIN_VIEW_DY )
, m_hOpenGlContext( NULL )
, m_nCameraIndex( 0L )
, m_strViewName( _T("noname") )
{
ASSERT( m_hWndOutput != NULL );
ASSERT( ::IsWindow(m_hWndOutput) );
_Init();
}
C3DView::~C3DView()
{
_Done();
}
bool C3DView::IsViewVisible() const
{
ASSERT_VALID( this );
ASSERT( m_hWndOutput != NULL );
ASSERT( ::IsWindow( ((HWND)m_hWndOutput) ) );
if( ::IsWindowVisible( ((HWND)m_hWndOutput) ) )
{
return (
::SendMessage(
m_hWndOutput,
GL_VIEWS_WM_QUERY_VIEW_VISIBILITY,
0L,
0L
) != 0
) ? true : false;
// HWND hWndParent = ::GetParent( m_hWndOutput );
// ASSERT( hWndParent != NULL );
// ASSERT( ::IsWindow( hWndParent ) );
// if( ::IsWindowVisible( hWndParent ) )
// return true;
}
return false;
}
void C3DView::Lock()
{
ASSERT_VALID( this );
m_csGDI.Lock();
}
void C3DView::Unlock()
{
ASSERT_VALID( this );
m_csGDI.Unlock();
}
void C3DView::_Init()
{
m_dc.SetViewSize( m_sizeView, false );
m_dc.GetInternalBitmap();
ASSERT( m_dc.GetSafeHdc() != NULL );
if( m_hOpenGlContext != NULL )
return;
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_SUPPORT_OPENGL|PFD_DRAW_TO_BITMAP,
PFD_TYPE_RGBA,
OnGlGetBufferBits(__EBB_COLOR),
0, 0, 0, 0, 0, 0,
OnGlGetBufferBits(__EBB_ALPHA),
0,
OnGlGetBufferBits(__EBB_ACCUM),
0, 0, 0, 0,
OnGlGetBufferBits(__EBB_Z),
OnGlGetBufferBits(__EBB_STENCIL),
OnGlGetBufferBits(__EBB_AUXILIARY),
PFD_MAIN_PLANE,
0,
0, 0, 0
};
GLuint PixelFormat = ChoosePixelFormat( m_dc.GetSafeHdc(), &pfd );
if( !PixelFormat )
{
OnGlAlertDisplay( _T("Failed to choose the pixel format") );
ASSERT( FALSE );
return;
}
if( !SetPixelFormat( m_dc.GetSafeHdc(), PixelFormat, &pfd ) )
{
OnGlAlertDisplay( _T("Failed to set the pixel format") );
ASSERT( FALSE );
return;
}
m_hOpenGlContext = wglCreateContext( m_dc.GetSafeHdc() );
if( m_hOpenGlContext == NULL )
{
OnGlAlertDisplay( _T("Failed to create OpenGL rendering context") );
ASSERT( FALSE );
return;
}
if( !wglMakeCurrent( m_dc.GetSafeHdc(), m_hOpenGlContext ) )
{
OnGlAlertDisplay( _T("Failed to activate OpenGL rendering context") );
ASSERT( FALSE );
return;
}
struct
{
LPCTSTR m_lpszResource;
} _texture_init_data[GL_VIEWS_TEXTURE_COUNT] =
{
{ MAKEINTRESOURCE(IDB_BITMAP_CUBE_ORANGE) },
{ MAKEINTRESOURCE(IDB_BITMAP_CUBE_WHITE) },
{ MAKEINTRESOURCE(IDB_BITMAP_RING) },
{ MAKEINTRESOURCE(IDB_BITMAP_BOTTOM_PLANE) },
{ MAKEINTRESOURCE(IDB_BITMAP_WND_AVI_PLAYER) },
{ MAKEINTRESOURCE(IDB_BITMAP_WND_AVI_PLAYER) }, // for surface
{ MAKEINTRESOURCE(IDB_BITMAP_WND_MIRROR) },
{ MAKEINTRESOURCE(IDB_BITMAP_EARTH) },
{ MAKEINTRESOURCE(IDB_BITMAP_MOON) },
};
glEnable( GL_TEXTURE_2D );
GL_VIEWS_CHECK_OPENGL_ERROR
for( int nTextureIdx = 0; nTextureIdx < GL_VIEWS_TEXTURE_COUNT; nTextureIdx++ )
{
C3DTexture objTexture;
if( !objTexture.LoadResourceBitmapAs32Bit(
_texture_init_data[nTextureIdx].m_lpszResource
)
)
{
ASSERT( FALSE );
return;
}
ASSERT( objTexture.IsAlphaLayerExist() );
objTexture.SetAlphaLayerIf( 180, RGB(245,21,3) );
objTexture.SetAlphaLayerIf( 0, RGB(0,0,0) );
glGenTextures( 1, &m_TextureIds[nTextureIdx] );
GL_VIEWS_CHECK_OPENGL_ERROR
glBindTexture( GL_TEXTURE_2D, m_TextureIds[nTextureIdx] );
GL_VIEWS_CHECK_OPENGL_ERROR
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
objTexture.GetWidth(),
objTexture.GetHeight(),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
objTexture.GetData()
);
GL_VIEWS_CHECK_OPENGL_ERROR
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
GL_VIEWS_CHECK_OPENGL_ERROR
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
GL_VIEWS_CHECK_OPENGL_ERROR
}
glDisable( GL_TEXTURE_2D );
GL_VIEWS_CHECK_OPENGL_ERROR
ASSERT( !m_Font3D.IsFontCreated() );
VERIFY( m_Font3D.CreateFont( m_dc.GetSafeHdc() ) );
if( !wglMakeCurrent( NULL, NULL ) )
{
OnGlAlertDisplay( _T("Failed to release contexts") );
ASSERT( FALSE );
return;
}
}
void C3DView::_Done()
{
m_Font3D.DeleteFont();
if( m_hOpenGlContext != NULL )
{
if( !wglDeleteContext( m_hOpenGlContext ) )
{
OnGlAlertDisplay( _T("Failed to release rendering context") );
ASSERT( FALSE );
}
m_hOpenGlContext = NULL;
} // if( m_hOpenGlContext != NULL )
m_dc.DeleteDC();
}
void C3DView::SetViewSize( CSize sizeView )
{
ASSERT_VALID( this );
ASSERT( m_sizeView.cx >= GL_VIEWS_MIN_VIEW_DX && m_sizeView.cy >= GL_VIEWS_MIN_VIEW_DY );
ASSERT( m_sizeViewNE.cx >= GL_VIEWS_MIN_VIEW_DX && m_sizeViewNE.cy >= GL_VIEWS_MIN_VIEW_DY );
Lock();
m_sizeViewNE.cx = max( GL_VIEWS_MIN_VIEW_DX, sizeView.cx );
m_sizeViewNE.cy = max( GL_VIEWS_MIN_VIEW_DY, sizeView.cy );
Unlock();
}
void C3DView::AdjustViewSize(
bool bLockView // = true
)
{
ASSERT_VALID( this );
if( m_sizeView == m_sizeViewNE )
return;
if( bLockView )
Lock();
ASSERT( m_sizeView.cx >= GL_VIEWS_MIN_VIEW_DX && m_sizeView.cy >= GL_VIEWS_MIN_VIEW_DY );
ASSERT( m_sizeViewNE.cx >= GL_VIEWS_MIN_VIEW_DX && m_sizeViewNE.cy >= GL_VIEWS_MIN_VIEW_DY );
_Done();
m_sizeView = m_sizeViewNE;
_Init();
if( bLockView )
Unlock();
}
void C3DView::DoStepLeft( GLfloat fStepSize )
{
ASSERT_VALID( this );
Lock();
C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
ASSERT_VALID( pCam );
pCam->DoStepLeft( fStepSize );
Unlock();
}
void C3DView::DoStepUp( GLfloat fStepSize )
{
ASSERT_VALID( this );
Lock();
C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
ASSERT_VALID( pCam );
pCam->DoStepUp( fStepSize );
Unlock();
}
void C3DView::DoStepForward( GLfloat fStepSize )
{
ASSERT_VALID( this );
Lock();
C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
ASSERT_VALID( pCam );
pCam->DoStepForward( fStepSize );
Unlock();
}
void C3DView::DoLookLeft( GLfloat fAngleDegrees )
{
ASSERT_VALID( this );
Lock();
C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
ASSERT_VALID( pCam );
pCam->DoLookLeft( fAngleDegrees );
Unlock();
}
void C3DView::DoLookUp( GLfloat fAngleDegrees )
{
ASSERT_VALID( this );
Lock();
C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
ASSERT_VALID( pCam );
pCam->DoLookUp( fAngleDegrees );
Unlock();
}
void C3DView::DoLookOwnAxis( GLfloat fAngleDegrees )
{
ASSERT_VALID( this );
Lock();
C3DCamera * pCam = the3DPipe.GetCamera( m_nCameraIndex );
ASSERT_VALID( pCam );
pCam->DoLookOwnAxis( fAngleDegrees );
Unlock();
}
/////////////////////////////////////////////////////////////////////////////
// C3DPipeThread
C3DPipeThread the3DPipe;
C3DPipeThread::C3DPipeThread()
: m_bInitComplete( false )
, m_eventShutdownStart( FALSE, FALSE, NULL, NULL )
, m_eventShutdownComplete( FALSE, FALSE, NULL, NULL )
, m_eventRenderViews( FALSE, FALSE, NULL, NULL )
, m_pRoot( new C3DObject(GL_VIEWS_ROOTNAME) )
, m_bTimerAnimationEnabled( false )
{
m_bAutoDelete = FALSE;
}
C3DPipeThread::~C3DPipeThread()
{
ASSERT( !m_bAutoDelete );
_ResourcesFree();
m_arrCams.RemoveAll();
delete m_pRoot;
}
bool C3DPipeThread::_ResourcesInit()
{
return true;
}
void C3DPipeThread::_ResourcesFree()
{
int nViewCount = m_arrViews.GetSize();
for( int nViewIdx = 0; nViewIdx < nViewCount; nViewIdx++ )
{
C3DView * pView3D = m_arrViews[nViewIdx];
ASSERT_VALID( pView3D );
delete pView3D;
}
m_arrViews.RemoveAll();
m_bInitComplete = false;
}
C3DObject * C3DPipeThread::GetRoot()
{
ASSERT_VALID( this );
ASSERT_VALID( m_pRoot );
return m_pRoot;
}
const C3DObject * C3DPipeThread::GetRoot() const
{
ASSERT_VALID( this );
ASSERT_VALID( m_pRoot );
return m_pRoot;
}
void C3DPipeThread::AddView( C3DView * pView3D )
{
ASSERT_VALID( this );
ASSERT_VALID( m_pRoot );
ASSERT_VALID( pView3D );
m_arrViews.Add( pView3D );
}
int C3DPipeThread::GetViewCount() const
{
ASSERT_VALID( this );
ASSERT_VALID( m_pRoot );
return m_arrViews.GetSize();
}
C3DView * C3DPipeThread::GetView( int nIndex )
{
ASSERT_VALID( this );
ASSERT_VALID( m_pRoot );
ASSERT( 0 <= nIndex && nIndex < m_arrViews.GetSize() );
C3DView * pView3D = m_arrViews[nIndex];
ASSERT_VALID( pView3D );
return pView3D;
}
void C3DPipeThread::AddCamera( C3DCamera * pCam )
{
ASSERT_VALID( this );
ASSERT_VALID( m_pRoot );
ASSERT_VALID( pCam );
ASSERT( !m_bInitComplete );
m_pRoot->AddChild( pCam );
m_arrCams.Add( pCam );
}
int C3DPipeThread::GetCameraCount() const
{
ASSERT_VALID( this );
ASSERT_VALID( m_pRoot );
return m_arrCams.GetSize();
}
C3DCamera * C3DPipeThread::GetCamera( int nIndex )
{
ASSERT_VALID( this );
ASSERT_VALID( m_pRoot );
ASSERT( 0 <= nIndex && nIndex < m_arrCams.GetSize() );
C3DCamera * pCam = m_arrCams[nIndex];
ASSERT_VALID( pCam );
return pCam;
}
void C3DPipeThread::Render()
{
m_eventRenderViews.SetEvent();
}
void C3DPipeThread::ShutdownAndWaitFor()
{
if( !m_bInitComplete )
return;
m_eventShutdownStart.SetEvent();
for( CExtPopupMenuWnd::PassMsgLoop(false);
!m_eventShutdownComplete.Lock(500);
CExtPopupMenuWnd::PassMsgLoop(false)
);
}
BOOL C3DPipeThread::InitInstance()
{
if( !_ResourcesInit() )
{
ASSERT( FALSE );
return FALSE;
}
ASSERT( m_arrViews.GetSize() > 0 );
m_bInitComplete = true;
return TRUE;
}
void C3DPipeThread::Delete()
{
ASSERT( !m_bAutoDelete );
_ResourcesFree();
CWinThread::Delete();
}
int C3DPipeThread::Run()
{
ASSERT( m_bInitComplete );
ASSERT_VALID( m_pRoot );
ObjectWriteAccessSet( true );
m_pRoot->WalkTree(
C3DObject::EWTQ_THREAD_INIT,
NULL,
NULL,
NULL,
NULL
);
ObjectWriteAccessSet( false );
int nViewCount = m_arrViews.GetSize();
ASSERT( nViewCount > 0 );
CSyncObject * arrToWait[2] =
{
&m_eventShutdownStart,
&m_eventRenderViews
};
CMultiLock _ml( arrToWait, 2, FALSE );
for( ; true; )
{
DWORD dwWaitResult = _ml.Lock( INFINITE, FALSE, 0 );
if( dwWaitResult != (WAIT_OBJECT_0 + 1) )
break;
bool bResetWriteAccess = false;
for( int nViewIdx = 0; nViewIdx < nViewCount; nViewIdx++ )
{
C3DView * pView3D = m_arrViews[nViewIdx];
ASSERT_VALID( pView3D );
if( !pView3D->IsViewVisible() )
continue;
bool bSendMsgComplete = false;
pView3D->Lock();
ASSERT( !pView3D->m_strViewName.IsEmpty() );
pView3D->AdjustViewSize( false );
ASSERT( pView3D->Get3DDC().GetSafeHdc() != NULL );
if( pView3D->Get3DDC().GetSafeHdc() != NULL )
{
if( !bResetWriteAccess )
{
ObjectWriteAccessSet( true );
bResetWriteAccess = true;
}
ASSERT( GetCameraCount() > 0 );
C3DCamera * pCam = GetCamera( pView3D->GetCameraIndex() );
ASSERT_VALID( pCam );
m_pRoot->WalkTree(
C3DObject::EWTQ_TRANSFORM,
pCam,
pView3D,
NULL,
NULL
);
if( !wglMakeCurrent( pView3D->Get3DDC().GetSafeHdc(), pView3D->GetOpenGlContext() ) )
{
pView3D->OnGlAlertDisplay( _T("Failed to activate OpenGL rendering context") );
ASSERT( FALSE );
continue;
} // if( !wglMakeCurrent( pView3D->Get3DDC().GetSafeHdc(), pView3D->GetOpenGlContext() ) )
else
{
#ifdef _DEBUG
static int g_nRenderCounter = 0;
TRACE2( " >>> 3D-PIPE: rendering %s images (counter=%d)\n", (LPCTSTR)pView3D->m_strViewName, g_nRenderCounter );
g_nRenderCounter++;
#endif // _DEBUG
glShadeModel( GL_SMOOTH );
GL_VIEWS_CHECK_OPENGL_ERROR
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
GL_VIEWS_CHECK_OPENGL_ERROR
glClearDepth( 1.0f );
GL_VIEWS_CHECK_OPENGL_ERROR
glEnable( GL_DEPTH_TEST );
GL_VIEWS_CHECK_OPENGL_ERROR
glDepthFunc( GL_LEQUAL );
GL_VIEWS_CHECK_OPENGL_ERROR
glDepthMask( GL_TRUE );
GL_VIEWS_CHECK_OPENGL_ERROR
glClearStencil( 0 );
GL_VIEWS_CHECK_OPENGL_ERROR
glEnable( GL_CULL_FACE );
GL_VIEWS_CHECK_OPENGL_ERROR
glCullFace( GL_FRONT );
GL_VIEWS_CHECK_OPENGL_ERROR
glFrontFace( GL_CW );
GL_VIEWS_CHECK_OPENGL_ERROR
glClear(
GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT
|GL_STENCIL_BUFFER_BIT
);
GL_VIEWS_CHECK_OPENGL_ERROR
glColorMask( 1, 1, 1, 1 );
GL_VIEWS_CHECK_OPENGL_ERROR
CSize _sizeView3D = pView3D->GetViewSize();
pCam->m_fAspect =
((GLfloat)_sizeView3D.cx)
/ ((GLfloat)_sizeView3D.cy)
;
glViewport(
0,
0,
_sizeView3D.cx,
_sizeView3D.cy
);
GL_VIEWS_CHECK_OPENGL_ERROR
glMatrixMode( GL_PROJECTION );
GL_VIEWS_CHECK_OPENGL_ERROR
_mt mtxPerspective;
mtxPerspective.load_perspective(
pCam->GetFov(),
pCam->m_fAspect,
pCam->m_fNearPlane,
pCam->m_fFarPlane
);
glLoadMatrixf( mtxPerspective.arr );
GL_VIEWS_CHECK_OPENGL_ERROR
glMatrixMode( GL_MODELVIEW );
GL_VIEWS_CHECK_OPENGL_ERROR
_mt _mtxCameraInversion( pCam->m_mtxLastTransformation );
_mtxCameraInversion.load_inversion();
glLoadMatrixf(_mtxCameraInversion.arr);
GL_VIEWS_CHECK_OPENGL_ERROR
m_pRoot->WalkTree(
C3DObject::EWTQ_RENDER,
pCam,
pView3D,
NULL,
NULL
);
glFinish();
GL_VIEWS_CHECK_OPENGL_ERROR
if( !wglMakeCurrent( NULL, NULL ) )
{
pView3D->OnGlAlertDisplay( _T("Failed to release contexts") );
ASSERT( FALSE );
}
bSendMsgComplete = true;
} // else from if( !wglMakeCurrent( pView3D->Get3DDC().GetSafeHdc(), pView3D->GetOpenGlContext() ) )
} // if( pView3D->Get3DDC().GetSafeHdc() != NULL )
pView3D->Unlock();
if( bSendMsgComplete )
{
if( bResetWriteAccess )
{
ObjectWriteAccessSet( false );
bResetWriteAccess = false;
}
::SendMessage(
pView3D->GetOutputHWND(),
GL_VIEWS_WM_RENDER_FRAME_COMPLETE,
0L,
0L
);
}
} // for( int nViewIdx = 0; nViewIdx < nViewCount; nViewIdx++ )
if( m_bTimerAnimationEnabled )
{
#ifdef _DEBUG
static int g_nRecalcPosCounter = 0;
TRACE1( " >>> 3D-PIPE: recalculating object positions (counter=%d)\n", g_nRecalcPosCounter );
g_nRecalcPosCounter++;
#endif // _DEBUG
if( !bResetWriteAccess )
{
ObjectWriteAccessSet( true );
bResetWriteAccess = true;
}
m_pRoot->WalkTree(
C3DObject::EWTQ_PLAY,
NULL,
NULL,
NULL,
NULL
);
} // if( m_bTimerAnimationEnabled )
if( bResetWriteAccess )
{
ObjectWriteAccessSet( false );
bResetWriteAccess = false;
}
} // for( ; true; )
ObjectWriteAccessSet( true );
m_pRoot->WalkTree(
C3DObject::EWTQ_THREAD_DONE,
NULL,
NULL,
NULL,
NULL
);
ObjectWriteAccessSet( false );
_ResourcesFree();
m_eventShutdownComplete.SetEvent();
return 0L;
}
/////////////////////////////////////////////////////////////////////////////
// CCameraSelectionComboBox
IMPLEMENT_DYNAMIC( CCameraSelectionComboBox, CExtComboBox )
CCameraSelectionComboBox::CCameraSelectionComboBox()
{
}
CCameraSelectionComboBox::~CCameraSelectionComboBox()
{
}
BEGIN_MESSAGE_MAP( CCameraSelectionComboBox, CExtComboBox )
//{{AFX_MSG_MAP(CCameraSelectionComboBox)
//}}AFX_MSG_MAP
ON_CONTROL_REFLECT(CBN_SELENDOK,OnReflectCbnSelEndOK)
END_MESSAGE_MAP()
void CCameraSelectionComboBox::SyncCameraWithSelectedItem(
bool bSetFocusToView // = false
)
{
ASSERT_VALID( this );
CWnd * pWnd = GetParent();
ASSERT_VALID( pWnd );
ASSERT_KINDOF( CExtToolControlBar, pWnd );
CChildView * pChildView = STATIC_DOWNCAST( CChildView, pWnd->GetParent() );
ASSERT_VALID( pChildView );
C3DView * pView3D = pChildView->m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
int nCurSel = GetCurSel();
ASSERT( 0 <= nCurSel && nCurSel < GL_VIEWS_CAMERA_COUNT );
int nCamIdxOld = pView3D->GetCameraIndex();
ASSERT( 0 <= nCamIdxOld && nCamIdxOld < GL_VIEWS_CAMERA_COUNT );
if( nCamIdxOld != nCurSel )
{
pView3D->SetCameraIndex( nCurSel );
} // if( nCamIdxOld != nCurSel )
if( bSetFocusToView )
pChildView->SetFocus();
if( nCamIdxOld != nCurSel )
{
CFrameWnd * pFrame = GetParentFrame();
ASSERT_VALID( pFrame );
CMainFrame * pMainFrame =
DYNAMIC_DOWNCAST( CMainFrame, pFrame );
if( pMainFrame == NULL )
{
pMainFrame =
DYNAMIC_DOWNCAST( CMainFrame, pFrame->GetParentFrame() );
ASSERT_VALID( pMainFrame );
}
pMainFrame->SyncCameraFovValue();
} // if( nCamIdxOld != nCurSel )
the3DPipe.Render();
}
int CCameraSelectionComboBox::SetCurSel(
int nSelect,
bool bSetFocusToView // = false
)
{
ASSERT( 0 <= nSelect && nSelect < GL_VIEWS_CAMERA_COUNT );
int nRetVal = CExtComboBox::SetCurSel( nSelect );
SyncCameraWithSelectedItem( bSetFocusToView );
return nRetVal;
}
void CCameraSelectionComboBox::OnReflectCbnSelEndOK()
{
ASSERT_VALID( this );
bool bSetFocusToView = false;
HWND hWndFocus = ::GetFocus();
if( hWndFocus == m_hWnd )
bSetFocusToView = true;
SyncCameraWithSelectedItem( bSetFocusToView );
}
/////////////////////////////////////////////////////////////////////////////
// CCameraFovComboBox
IMPLEMENT_DYNAMIC( CCameraFovComboBox, CExtComboBox )
CCameraFovComboBox::CCameraFovComboBox()
{
}
CCameraFovComboBox::~CCameraFovComboBox()
{
}
BEGIN_MESSAGE_MAP( CCameraFovComboBox, CExtComboBox )
//{{AFX_MSG_MAP(CCameraFovComboBox)
//}}AFX_MSG_MAP
ON_CONTROL_REFLECT(CBN_SELENDOK,OnReflectCbnSelEndOK)
END_MESSAGE_MAP()
void CCameraFovComboBox::SyncCameraWithSelectedItem(
bool bSetFocusToView // = false
)
{
ASSERT_VALID( this );
CWnd * pWnd = GetParent();
ASSERT_VALID( pWnd );
ASSERT_KINDOF( CExtToolControlBar, pWnd );
CChildView * pChildView = STATIC_DOWNCAST( CChildView, pWnd->GetParent() );
ASSERT_VALID( pChildView );
C3DView * pView3D = pChildView->m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
int nCamIdx = pView3D->GetCameraIndex();
ASSERT( 0 <= nCamIdx && nCamIdx < GL_VIEWS_CAMERA_COUNT );
C3DCamera * pCam = the3DPipe.GetCamera( nCamIdx );
ASSERT_VALID( pCam );
int nFovIdx = GetCurSel();
ASSERT( 0 <= nFovIdx && nFovIdx < GL_VIEWS_FOV_COUNT );
bool bRender = false;
the3DPipe.ObjectWriteAccessSet( true );
if( pCam->m_nFovIndex != nFovIdx )
{
pCam->m_nFovIndex = nFovIdx;
bRender = true;
}
the3DPipe.ObjectWriteAccessSet( false );
if( bSetFocusToView )
pChildView->SetFocus();
if( bRender )
{
CFrameWnd * pFrame = GetParentFrame();
ASSERT_VALID( pFrame );
CMainFrame * pMainFrame =
DYNAMIC_DOWNCAST( CMainFrame, pFrame );
if( pMainFrame == NULL )
{
pMainFrame =
DYNAMIC_DOWNCAST( CMainFrame, pFrame->GetParentFrame() );
ASSERT_VALID( pMainFrame );
}
pMainFrame->SyncCameraFovValue( nCamIdx, nFovIdx );
the3DPipe.Render();
}
}
int CCameraFovComboBox::SetCurSel(
int nSelect,
bool bSetFocusToView // = false
)
{
ASSERT( 0 <= nSelect && nSelect < GL_VIEWS_FOV_COUNT );
int nRetVal = CExtComboBox::SetCurSel( nSelect );
SyncCameraWithSelectedItem( bSetFocusToView );
return nRetVal;
}
void CCameraFovComboBox::OnReflectCbnSelEndOK()
{
ASSERT_VALID( this );
bool bSetFocusToView = false;
HWND hWndFocus = ::GetFocus();
if( hWndFocus == m_hWnd )
bSetFocusToView = true;
SyncCameraWithSelectedItem( bSetFocusToView );
}
/////////////////////////////////////////////////////////////////////////////
// CObjectHierarchyTreeCtrl
IMPLEMENT_DYNAMIC( CObjectHierarchyTreeCtrl, CTreeCtrl )
CObjectHierarchyTreeCtrl::CObjectHierarchyTreeCtrl()
{
}
CObjectHierarchyTreeCtrl::~CObjectHierarchyTreeCtrl()
{
}
BEGIN_MESSAGE_MAP( CObjectHierarchyTreeCtrl, CTreeCtrl )
//{{AFX_MSG_MAP(CObjectHierarchyTreeCtrl)
ON_WM_LBUTTONDBLCLK()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CObjectHierarchyTreeCtrl message handlers
void CObjectHierarchyTreeCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
{
CTreeCtrl::OnLButtonDblClk(nFlags, point);
UINT htFlags = 0L;
HTREEITEM _hti = CTreeCtrl::HitTest( point, &htFlags );
if( _hti != NULL
&& (htFlags&(TVHT_ONITEM)) != 0
)
{
C3DObject * pObj = (C3DObject *)
CTreeCtrl::GetItemData( _hti );
ASSERT( pObj != NULL );
ASSERT_VALID( pObj );
ASSERT_KINDOF( C3DObject, pObj );
pObj->OnTreeItemDblClick( this );
}
}
/////////////////////////////////////////////////////////////////////////////
// CChildView
IMPLEMENT_DYNAMIC( CChildView, CWnd )
GLfloat CChildView::g_fStepRotationAngle = 2.0f;
GLfloat CChildView::g_fStepWalkSize = 0.02f;
CChildView::CChildView(
UINT nIdResourceCursor
)
: m_wndGlPanel( nIdResourceCursor )
{
ASSERT( (ID_SELCAM9) == (ID_SELCAM8 + 1) );
ASSERT( (ID_SELCAM8) == (ID_SELCAM7 + 1) );
ASSERT( (ID_SELCAM7) == (ID_SELCAM6 + 1) );
ASSERT( (ID_SELCAM6) == (ID_SELCAM5 + 1) );
ASSERT( (ID_SELCAM5) == (ID_SELCAM4 + 1) );
ASSERT( (ID_SELCAM4) == (ID_SELCAM3 + 1) );
ASSERT( (ID_SELCAM3) == (ID_SELCAM2 + 1) );
ASSERT( (ID_SELCAM2) == (ID_SELCAM1 + 1) );
ASSERT( (ID_SELCAM1) == (ID_SELCAM0 + 1) );
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP( CChildView, CWnd )
//{{AFX_MSG_MAP(CChildView)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_CREATE()
ON_WM_SIZE()
ON_COMMAND(ID_ROTATE_ABOUT_X0, OnRotateAboutX0)
ON_COMMAND(ID_ROTATE_ABOUT_X1, OnRotateAboutX1)
ON_COMMAND(ID_ROTATE_ABOUT_Y0, OnRotateAboutY0)
ON_COMMAND(ID_ROTATE_ABOUT_Y1, OnRotateAboutY1)
ON_COMMAND(ID_ROTATE_ABOUT_Z0, OnRotateAboutZ0)
ON_COMMAND(ID_ROTATE_ABOUT_Z1, OnRotateAboutZ1)
ON_COMMAND(ID_TRANSLATE_X0, OnTranslateX0)
ON_COMMAND(ID_TRANSLATE_X1, OnTranslateX1)
ON_COMMAND(ID_TRANSLATE_Y0, OnTranslateY0)
ON_COMMAND(ID_TRANSLATE_Y1, OnTranslateY1)
ON_COMMAND(ID_TRANSLATE_Z0, OnTranslateZ0)
ON_COMMAND(ID_TRANSLATE_Z1, OnTranslateZ1)
ON_WM_SETFOCUS()
ON_WM_CONTEXTMENU()
ON_UPDATE_COMMAND_UI(ID_BTN_MENU_ROTATION, OnUpdateEnabledBtnInBar)
ON_COMMAND(ID_CAM_FOV_INC, OnCamFovInc)
ON_UPDATE_COMMAND_UI(ID_CAM_FOV_INC, OnUpdateCamFovInc)
ON_COMMAND(ID_CAM_FOV_DEC, OnCamFovDec)
ON_UPDATE_COMMAND_UI(ID_CAM_FOV_DEC, OnUpdateCamFovDec)
//}}AFX_MSG_MAP
ON_COMMAND_RANGE( ID_SELCAM0, ID_SELCAM9, OnSelectCamera )
ON_UPDATE_COMMAND_UI_RANGE( ID_SELCAM0, ID_SELCAM9, OnUpdateSelectCamera )
ON_UPDATE_COMMAND_UI( ID_CAMERA_SELECTION_COMBO, OnUpdateEnabledBtnInBar )
ON_UPDATE_COMMAND_UI( ID_CAMERA_FOV_COMBO, OnUpdateEnabledBtnInBar )
ON_UPDATE_COMMAND_UI( ID_BTN_MENU_ROTATION, OnUpdateEnabledBtnInBar )
ON_UPDATE_COMMAND_UI( ID_BTN_MENU_TRANSLATION, OnUpdateEnabledBtnInBar )
ON_REGISTERED_MESSAGE(
CExtPopupMenuWnd::g_nMsgPrepareMenu,
OnExtMenuPrepare
)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChildView message handlers
LRESULT CChildView::OnExtMenuPrepare(WPARAM wParam, LPARAM lParam)
{
lParam;
CExtPopupMenuWnd::MsgPrepareMenuData_t * pData =
reinterpret_cast
< CExtPopupMenuWnd::MsgPrepareMenuData_t * >
( wParam );
ASSERT( pData != NULL );
CExtPopupMenuWnd * pPopup = pData->m_pPopup;
ASSERT( pPopup != NULL );
// remove camera selection combo command
INT nPos = pPopup->ItemFindPosForCmdID(ID_CAMERA_SELECTION_COMBO);
if( nPos >= 0 )
pPopup->ItemRemove( nPos );
if( pPopup->ItemGetCount() > 0
&& pPopup->ItemGetInfo(0).IsSeparator()
)
pPopup->ItemRemove( 0 );
// replace camera FOV combo command
nPos = pPopup->ItemFindPosForCmdID(ID_CAMERA_FOV_COMBO);
if( nPos >= 0 )
{
pPopup->ItemRemove( nPos );
if( pPopup->ItemInsert(
(UINT)CExtPopupMenuWnd::TYPE_POPUP,
nPos,
_T("Camera FOV"),
NULL,
m_hWnd
)
)
{
CExtPopupMenuWnd * pSubMenu =
pPopup->ItemGetPopup( nPos );
ASSERT_VALID( pSubMenu );
VERIFY(
pSubMenu->ItemInsert(
ID_CAM_FOV_INC,
-1,
NULL,
NULL,
m_hWnd
)
);
VERIFY(
pSubMenu->ItemInsert(
ID_CAM_FOV_DEC,
-1,
NULL,
NULL,
m_hWnd
)
);
UpdateDialogControls( this, TRUE );
}
#ifdef _DEBUG
else
{
ASSERT( FALSE );
}
#endif // _DEBUG
}
// remove leading separator if exist
if( pPopup->ItemGetCount() > 0
&& pPopup->ItemGetInfo(0).IsSeparator()
)
pPopup->ItemRemove( 0 );
return TRUE;
}
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if( ! (CExtWRB < CWnd > ::PreCreateWindow(cs) ) )
return FALSE;
cs.dwExStyle &= ~(WS_EX_STATICEDGE|WS_EX_CLIENTEDGE);
cs.style &= ~WS_BORDER;
cs.style |= WS_CLIPSIBLINGS;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);
return TRUE;
}
void CChildView::OnPaint()
{
CPaintDC dcPaint( this );
CExtPaintManager::stat_ExcludeChildAreas(
dcPaint.GetSafeHdc(),
GetSafeHwnd()
);
}
BOOL CChildView::OnEraseBkgnd(CDC* pDC)
{
pDC;
return TRUE;
}
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if( CExtWRB < CWnd >::OnCreate(lpCreateStruct) == -1 )
{
ASSERT( FALSE );
return -1;
}
m_wndToolbar.m_bPresubclassDialogMode = true;
if( !m_wndToolbar.Create(
_T(""),
this,
AFX_IDW_DIALOGBAR,
WS_CHILD|WS_VISIBLE
|CBRS_ALIGN_TOP|CBRS_TOOLTIPS
|CBRS_FLYBY|CBRS_SIZE_DYNAMIC
)
)
{
ASSERT( FALSE );
return -1;
}
if( !m_wndToolbar.LoadToolBar(IDR_TOOLBAR_INVIEW) )
{
ASSERT( FALSE );
return -1;
}
if( !m_wndToolbar.InitNavigationBar() )
return -1;
if( !m_wndGlPanel.Create(
this,
GL_VIEWS_ID_VIEW_DLG_CTRL_ID
)
)
{
ASSERT( FALSE );
return -1;
}
m_wndGlPanel.SetFont( CFont::FromHandle((HFONT)::GetStockObject(DEFAULT_GUI_FONT)) );
CWnd::RepositionBars( 0, 0xFFFF, GL_VIEWS_ID_VIEW_DLG_CTRL_ID );
return 0;
}
void CChildView::OnSize(UINT nType, int cx, int cy)
{
CExtWRB < CWnd > ::OnSize(nType, cx, cy);
if( nType != SIZE_MINIMIZED )
CWnd::RepositionBars( 0, 0xFFFF, GL_VIEWS_ID_VIEW_DLG_CTRL_ID );
}
void CChildView::OnUpdateEnabledBtnInBar(CCmdUI* pCmdUI)
{
ASSERT( pCmdUI != NULL );
pCmdUI->Enable();
}
void CChildView::OnSetFocus(CWnd* pOldWnd)
{
CWnd ::OnSetFocus(pOldWnd);
m_wndGlPanel.SetFocus();
}
void CChildView::OnContextMenu(CWnd* pWnd, CPoint point)
{
pWnd;
point;
}
void CChildView::OnRotateAboutX0()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoLookUp( g_fStepRotationAngle );
the3DPipe.Render();
}
void CChildView::OnRotateAboutX1()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoLookUp( -g_fStepRotationAngle );
the3DPipe.Render();
}
void CChildView::OnRotateAboutY0()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoLookLeft( g_fStepRotationAngle );
the3DPipe.Render();
}
void CChildView::OnRotateAboutY1()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoLookLeft( -g_fStepRotationAngle );
the3DPipe.Render();
}
void CChildView::OnRotateAboutZ0()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoLookOwnAxis( g_fStepRotationAngle );
the3DPipe.Render();
}
void CChildView::OnRotateAboutZ1()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoLookOwnAxis( -g_fStepRotationAngle );
the3DPipe.Render();
}
void CChildView::OnTranslateX0()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoStepLeft( g_fStepWalkSize );
the3DPipe.Render();
}
void CChildView::OnTranslateX1()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoStepLeft( -g_fStepWalkSize );
the3DPipe.Render();
}
void CChildView::OnTranslateY0()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoStepUp( g_fStepWalkSize );
the3DPipe.Render();
}
void CChildView::OnTranslateY1()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoStepUp( -g_fStepWalkSize );
the3DPipe.Render();
}
void CChildView::OnTranslateZ0()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoStepForward( g_fStepWalkSize );
the3DPipe.Render();
}
void CChildView::OnTranslateZ1()
{
ASSERT_VALID( this );
C3DView * pView3D = m_wndGlPanel.GetView3D();
if( pView3D == NULL )
return;
ASSERT_VALID( pView3D );
pView3D->DoStepForward( -g_fStepWalkSize );
the3DPipe.Render();
}
void CChildView::OnSelectCamera( UINT nCmdID )
{
ASSERT_VALID( this );
ASSERT( ID_SELCAM0 <= nCmdID && nCmdID <= ID_SELCAM9 );
int nCameraIndex = nCmdID - ID_SELCAM0;
ASSERT( 0 <= nCameraIndex && nCameraIndex < GL_VIEWS_CAMERA_COUNT );
m_wndToolbar.m_wndCameraSelCombo.SetCurSel( nCameraIndex );
}
void CChildView::OnUpdateSelectCamera(CCmdUI* pCmdUI)
{
ASSERT_VALID( this );
ASSERT( pCmdUI != NULL );
ASSERT( ID_SELCAM0 <= pCmdUI->m_nID && pCmdUI->m_nID <= ID_SELCAM9 );
int nCameraIndexReal = m_wndToolbar.m_wndCameraSelCombo.GetCurSel();
if( nCameraIndexReal < 0 )
{
pCmdUI->Enable( FALSE );
return;
}
ASSERT( 0 <= nCameraIndexReal && nCameraIndexReal < GL_VIEWS_CAMERA_COUNT );
int nCameraIndexToCmp = pCmdUI->m_nID - ID_SELCAM0;
ASSERT( 0 <= nCameraIndexToCmp && nCameraIndexToCmp < GL_VIEWS_CAMERA_COUNT );
pCmdUI->Enable( TRUE );
pCmdUI->SetRadio(
(nCameraIndexReal == nCameraIndexToCmp)
? TRUE
: FALSE
);
}
void CChildView::OnCamFovInc()
{
ASSERT_VALID( this );
int nCameraIndexReal = m_wndToolbar.m_wndCameraSelCombo.GetCurSel();
ASSERT(
( 0 <= nCameraIndexReal && nCameraIndexReal < GL_VIEWS_CAMERA_COUNT )
|| nCameraIndexReal < 0
);
if( nCameraIndexReal < 0 )
return;
C3DCamera * pCam = the3DPipe.GetCamera( nCameraIndexReal );
ASSERT_VALID( pCam );
int nFovIdx = pCam->m_nFovIndex;
ASSERT( 0 <= nFovIdx && nFovIdx < GL_VIEWS_FOV_COUNT );
if( nFovIdx == (GL_VIEWS_FOV_COUNT-1) )
return;
m_wndToolbar.m_wndCameraFovCombo.SetCurSel( nFovIdx+1, false );
}
void CChildView::OnUpdateCamFovInc(CCmdUI* pCmdUI)
{
ASSERT_VALID( this );
ASSERT( pCmdUI != NULL );
int nCameraIndexReal = m_wndToolbar.m_wndCameraSelCombo.GetCurSel();
ASSERT(
( 0 <= nCameraIndexReal && nCameraIndexReal < GL_VIEWS_CAMERA_COUNT )
|| nCameraIndexReal < 0
);
if( nCameraIndexReal < 0 )
{
pCmdUI->Enable( FALSE );
return;
}
C3DCamera * pCam = the3DPipe.GetCamera( nCameraIndexReal );
ASSERT_VALID( pCam );
int nFovIdx = pCam->m_nFovIndex;
ASSERT( 0 <= nFovIdx && nFovIdx < GL_VIEWS_FOV_COUNT );
pCmdUI->Enable(
(nFovIdx < (GL_VIEWS_FOV_COUNT-1)) ? TRUE : FALSE
);
}
void CChildView::OnCamFovDec()
{
ASSERT_VALID( this );
int nCameraIndexReal = m_wndToolbar.m_wndCameraSelCombo.GetCurSel();
ASSERT(
( 0 <= nCameraIndexReal && nCameraIndexReal < GL_VIEWS_CAMERA_COUNT )
|| nCameraIndexReal < 0
);
if( nCameraIndexReal < 0 )
return;
C3DCamera * pCam = the3DPipe.GetCamera( nCameraIndexReal );
ASSERT_VALID( pCam );
int nFovIdx = pCam->m_nFovIndex;
ASSERT( 0 <= nFovIdx && nFovIdx < GL_VIEWS_FOV_COUNT );
if( nFovIdx == 0 )
return;
m_wndToolbar.m_wndCameraFovCombo.SetCurSel( nFovIdx-1, false );
}
void CChildView::OnUpdateCamFovDec(CCmdUI* pCmdUI)
{
ASSERT_VALID( this );
ASSERT( pCmdUI != NULL );
int nCameraIndexReal = m_wndToolbar.m_wndCameraSelCombo.GetCurSel();
ASSERT(
( 0 <= nCameraIndexReal && nCameraIndexReal < GL_VIEWS_CAMERA_COUNT )
|| nCameraIndexReal < 0
);
if( nCameraIndexReal < 0 )
{
pCmdUI->Enable( FALSE );
return;
}
C3DCamera * pCam = the3DPipe.GetCamera( nCameraIndexReal );
ASSERT_VALID( pCam );
int nFovIdx = pCam->m_nFovIndex;
ASSERT( 0 <= nFovIdx && nFovIdx < GL_VIEWS_FOV_COUNT );
pCmdUI->Enable(
(nFovIdx > 0) ? TRUE : FALSE
);
}