0001:
0002:
0003:
0004:
0005:
0006: #include <windows.h>
0007: #include <GL/glut.h>
0008: #include "te_tms.h"
0009:
0010: #define DISPLAY_LIST
0011: #define NO_VBOS
0012:
0013: namespace Te
0014: {
0015:
0016: #define GL_ARRAY_BUFFER_ARB 0x8892
0017: #define GL_STATIC_DRAW_ARB 0x88E4
0018: typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
0019: typedef void (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
0020: typedef void (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
0021: typedef void (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
0022:
0023:
0024: PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
0025: PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
0026: PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;
0027: PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;
0028:
0029: bool CTms::_fVBOSupported = FALSE;
0030:
0031:
0032:
0033:
0034:
0035:
0036:
0037:
0038:
0039: PTMS SetupTms( const PTMS_DATA data )
0040: {
0041: CTms *pTms = new CTms( data );
0042:
0043: return (PTMS)pTms;
0044: }
0045:
0046:
0047:
0048:
0049: void ClenaTms( PTMS p )
0050: {
0051: CTms *pTms = (CTms *)p;
0052:
0053: delete pTms;
0054: }
0055:
0056:
0057:
0058:
0059: void RenderTms( PTMS p )
0060: {
0061: CTms *pTms = (CTms *)p;
0062:
0063: pTms->Render();
0064: }
0065:
0066:
0067:
0068:
0069:
0070:
0071:
0072:
0073:
0074: void CTms::Initialize()
0075: {
0076: CheckDeviceAbility();
0077: }
0078:
0079:
0080:
0081:
0082:
0083: CTms::CTms( const PTMS_DATA p )
0084: {
0085: const PTMS_HEADER pHeader = (const PTMS_HEADER)p;
0086: _nVertex = pHeader->vertex_count;
0087:
0088:
0089:
0090:
0091: _pPosition = (const float *)(pHeader+1);
0092: _pNormal = _pPosition + 3 * _nVertex;
0093: _pTexCoord = _pNormal + 3 * _nVertex;
0094:
0095: #ifdef DISPLAY_LIST
0096: _iDisplayList = glGenLists(1);
0097: glNewList( _iDisplayList, GL_COMPILE );
0098:
0099: glBegin( GL_TRIANGLES );
0100:
0101: for( unsigned int i = 0; i < _nVertex; i++ )
0102: {
0103: glNormal3fv ( _pNormal ); _pNormal += 3;
0104: glTexCoord2fv( _pTexCoord ); _pTexCoord += 2;
0105: glVertex3fv ( _pPosition ); _pPosition += 3;
0106: }
0107: glEnd();
0108:
0109: glEndList();
0110: #else
0111: #ifndef NO_VBOS
0112:
0113:
0114:
0115:
0116: glGenBuffersARB( 1, &_nVBOPosition );
0117: glBindBufferARB( GL_ARRAY_BUFFER_ARB, _nVBOPosition );
0118: glBufferDataARB( GL_ARRAY_BUFFER_ARB, _nVertex*3*sizeof(float), _pPosition, GL_STATIC_DRAW_ARB );
0119:
0120:
0121: glGenBuffersARB( 1, &_nVBONormal );
0122: glBindBufferARB( GL_ARRAY_BUFFER_ARB, _nVBONormal );
0123: glBufferDataARB( GL_ARRAY_BUFFER_ARB, _nVertex*3*sizeof(float), _pNormal, GL_STATIC_DRAW_ARB );
0124:
0125:
0126:
0127: glGenBuffersARB( 1, &_nVBOTexCoord );
0128: glBindBufferARB( GL_ARRAY_BUFFER_ARB, _nVBOTexCoord );
0129: glBufferDataARB( GL_ARRAY_BUFFER_ARB, _nVertex*2*sizeof(float), _pTexCoord, GL_STATIC_DRAW_ARB );
0130: #endif
0131: #endif
0132: }
0133:
0134:
0135:
0136:
0137:
0138: CTms::~CTms( )
0139: {
0140: #ifdef DISPLAY_LIST
0141: glDeleteLists( _iDisplayList, 1 );
0142: #endif
0143:
0144:
0145: if( _fVBOSupported )
0146: {
0147: unsigned int nBuffers[] = { _nVBOPosition, _nVBONormal, _nVBOTexCoord };
0148: glDeleteBuffersARB( 3, nBuffers );
0149: }
0150:
0151: _pTexCoord = 0;
0152: _pNormal = 0;
0153: _pPosition = 0;
0154: _nVertex = 0;
0155: }
0156:
0157:
0158:
0159:
0160: static bool IsExtensionSupported( char* szTargetExtension )
0161: {
0162: const unsigned char *pszExtensions = NULL;
0163: const unsigned char *pszStart;
0164: unsigned char *pszWhere, *pszTerminator;
0165:
0166:
0167: pszWhere = (unsigned char *) strchr( szTargetExtension, ' ' );
0168: if( pszWhere || *szTargetExtension == '\0' )
0169: return false;
0170:
0171:
0172: pszExtensions = glGetString( GL_EXTENSIONS );
0173:
0174:
0175: pszStart = pszExtensions;
0176: for(;;)
0177: {
0178: pszWhere = (unsigned char *) strstr( (const char *) pszStart, szTargetExtension );
0179: if( !pszWhere )
0180: break;
0181: pszTerminator = pszWhere + strlen( szTargetExtension );
0182: if( pszWhere == pszStart || *( pszWhere - 1 ) == ' ' )
0183: if( *pszTerminator == ' ' || *pszTerminator == '\0' )
0184: return true;
0185: pszStart = pszTerminator;
0186: }
0187: return false;
0188: }
0189:
0190:
0191:
0192:
0193: void CTms::CheckDeviceAbility()
0194: {
0195: #ifdef DISPLAY_LIST
0196: _fVBOSupported = false;
0197: return;
0198: #endif// DISPLAY_LIST
0199:
0200:
0201: #ifndef NO_VBOS
0202: _fVBOSupported = IsExtensionSupported( "GL_ARB_vertex_buffer_object" );
0203: if( _fVBOSupported )
0204: {
0205:
0206: glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) wglGetProcAddress("glGenBuffersARB");
0207: glBindBufferARB = (PFNGLBINDBUFFERARBPROC) wglGetProcAddress("glBindBufferARB");
0208: glBufferDataARB = (PFNGLBUFFERDATAARBPROC) wglGetProcAddress("glBufferDataARB");
0209: glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) wglGetProcAddress("glDeleteBuffersARB");
0210: }
0211: #else
0212: _fVBOSupported = false;
0213: #endif
0214: }
0215:
0216:
0217:
0218:
0219: void CTms::Render( )
0220: {
0221: #ifdef DISPLAY_LIST
0222: glCallList( _iDisplayList );
0223: #else
0224:
0225: glEnableClientState( GL_VERTEX_ARRAY );
0226: glEnableClientState( GL_NORMAL_ARRAY );
0227: glEnableClientState( GL_TEXTURE_COORD_ARRAY );
0228:
0229:
0230: if( _fVBOSupported )
0231: {
0232: glBindBufferARB( GL_ARRAY_BUFFER_ARB, _nVBOPosition );
0233: glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );
0234: glBindBufferARB( GL_ARRAY_BUFFER_ARB, _nVBONormal );
0235: glNormalPointer( GL_FLOAT, 0, (char *) NULL );
0236: glBindBufferARB( GL_ARRAY_BUFFER_ARB, _nVBOTexCoord );
0237: glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL );
0238: } else
0239: {
0240: glVertexPointer( 3, GL_FLOAT, 0, _pPosition );
0241: glNormalPointer( GL_FLOAT, 0, _pNormal );
0242: glTexCoordPointer( 2, GL_FLOAT, 0, _pTexCoord );
0243: }
0244:
0245:
0246: glDrawArrays( GL_TRIANGLES, 0, _nVertex );
0247:
0248:
0249: glDisableClientState( GL_VERTEX_ARRAY );
0250: glDisableClientState( GL_NORMAL_ARRAY );
0251: glDisableClientState( GL_TEXTURE_COORD_ARRAY );
0252: #endif
0253: }
0254:
0255: }
0256: