1 class CBIKMaterial 2 { 3 public: 4 CBIKMaterial(); 5 ~CBIKMaterial(); 6 7 bool Init(const char *pFileName); 8 void Shutdown(void); 9 bool Update(void); 10 int GetTexture(void); 11 void GetFrameSize(int *pWidth, int *pHeight); 12 int GetFrameRate(void); 13 int GetFrameCount(void); 14 void SetFrame(float flFrame); 15 void SetLoop(bool state); 16 17 private: 18 void CreateProceduralTexture(void); 19 void DestroyProceduralTexture(void); 20 21 int m_Texture; 22 23 HBINK m_pHBINK; 24 25 U8 *m_pBuffer; 26 U32 m_nBufferSize; 27 28 int m_nBIKWidth; 29 int m_nBIKHeight; 30 31 int m_nFrameRate; 32 int m_nFrameCount; 33 34 bool m_bLoop; 35 36 HBINKTRACK m_hTrack; 37 38 U8 *m_pSampleData; 39 U32 m_nSampleSize; 40 41 public: 42 float *m_pWaveData; 43 U32 m_nWaveSize; 44 }; 45 46 CBIKMaterial::CBIKMaterial() 47 { 48 m_pHBINK = NULL; 49 } 50 51 CBIKMaterial::~CBIKMaterial() 52 { 53 } 54 55 bool CBIKMaterial::Init(const char *pFileName) 56 { 57 m_pHBINK = BinkOpen(pFileName, BINKSNDTRACK); 58 59 if (!m_pHBINK) 60 { 61 m_nBIKWidth = 64; 62 m_nBIKHeight = 64; 63 m_nFrameRate = 1; 64 m_nFrameCount = 1; 65 66 return false; 67 } 68 69 m_nBIKWidth = m_pHBINK->Width; 70 m_nBIKHeight = m_pHBINK->Height; 71 72 m_nFrameRate = (int)((float)m_pHBINK->FrameRate / (float)m_pHBINK->FrameRateDiv); 73 m_nFrameCount = m_pHBINK->Frames; 74 75 m_nBufferSize = m_nBIKWidth * m_nBIKHeight * 3; // RGB(A) 76 77 m_pBuffer = new U8[m_nBufferSize]; 78 memset(m_pBuffer, 0, m_nBufferSize); 79 80 CreateProceduralTexture(); 81 82 if (m_pHBINK->NumTracks) 83 { 84 m_hTrack = BinkOpenTrack(m_pHBINK, 0); 85 86 BINKTRACK *track = (BINKTRACK *)m_hTrack; 87 88 m_nSampleSize = track->MaxSize; 89 m_pSampleData = new U8[m_nSampleSize]; 90 91 m_nWaveSize = 2048; 92 m_pWaveData = new float[m_nWaveSize]; 93 } 94 95 for (int i = 0; i < m_pHBINK->NumTracks; ++i) 96 { 97 BinkSetVolume(m_pHBINK, BinkGetTrackID(m_pHBINK, i), 0xFFFF); 98 } 99 100 return true;101 }102 103 void CBIKMaterial::Shutdown(void)104 {105 DestroyProceduralTexture();106 107 if (m_pHBINK)108 {109 BinkClose(m_pHBINK);110 m_pHBINK = NULL;111 }112 113 if (m_pBuffer)114 {115 delete[] m_pBuffer;116 m_pBuffer = NULL;117 }118 }119 120 bool CBIKMaterial::Update(void)121 {122 BinkDoFrame(m_pHBINK);123 124 if (BinkWait(m_pHBINK))125 return true;126 127 while (BinkShouldSkip(m_pHBINK))128 {129 BinkNextFrame(m_pHBINK);130 BinkDoFrame(m_pHBINK);131 }132 133 if (m_pHBINK->FrameNum == m_pHBINK->Frames)134 {135 if (m_bLoop)136 {137 BinkGoto(m_pHBINK, 0, 0);138 }139 140 return false;141 }142 143 BinkCopyToBuffer(m_pHBINK, m_pBuffer, m_nBIKWidth * 3, m_nBIKHeight, 0, 0, BINKSURFACE24R);144 glBindTexture(GL_TEXTURE_2D, m_Texture);145 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_nBIKWidth, m_nBIKHeight, GL_RGB, GL_UNSIGNED_BYTE, m_pBuffer);146 147 if (m_pHBINK->NumTracks && m_pSampleData)148 {149 memset(m_pSampleData, 0, m_nSampleSize);150 BinkGetTrackData(m_hTrack, m_pSampleData);151 152 BINKTRACK *track = (BINKTRACK *)m_hTrack;153 int i, n;154 155 memset(m_pWaveData, 0, m_nWaveSize);156 157 if (track->Channels == 1 && track->Bits == 8)158 {159 for (i = 0, n = 0; i < m_nSampleSize && n < m_nWaveSize; )160 {161 m_pWaveData[n] = (float)m_pSampleData[i] / 128.0f;162 ++i;163 ++n;164 }165 }166 else if (track->Channels == 2 && track->Bits == 8)167 {168 for (i = 0, n = 0; i < m_nSampleSize && n < m_nWaveSize; )169 {170 float l = (float)m_pSampleData[i] / 128.0f;171 ++i;172 float r = (float)m_pSampleData[i] / 128.0f;173 ++i;174 175 m_pWaveData[n] = (l + r) / 2.0f;176 ++n;177 }178 }179 else if (track->Channels == 1 && track->Bits == 16)180 {181 for (i = 0, n = 0; i < m_nSampleSize && n < m_nWaveSize; )182 {183 m_pWaveData[n] = (float)( (m_pSampleData[i + 1] << 8) + 184 m_pSampleData[i]) / 32767.0f;185 186 i += 2;187 ++n;188 }189 }190 else if (track->Channels == 2 && track->Bits == 16)191 {192 for (i = 0, n = 0; i < m_nSampleSize && n < m_nWaveSize; )193 {194 float l = (float)( (m_pSampleData[i + 1] << 8) + 195 m_pSampleData[i]) / 32767.0f;196 float r = (float)( (m_pSampleData[i + 3] << 8) + 197 m_pSampleData[i + 2]) / 32767.0f;198 199 i += 4;200 201 m_pWaveData[n] = (l + r) / 2.0f;202 ++n;203 }204 }205 }206 207 BinkNextFrame(m_pHBINK);208 209 return true;210 }211 212 int CBIKMaterial::GetTexture(void)213 {214 return m_Texture;215 }216 217 void CBIKMaterial::GetFrameSize(int *pWidth, int *pHeight)218 {219 *pWidth = m_nBIKWidth;220 *pHeight = m_nBIKHeight;221 }222 223 int CBIKMaterial::GetFrameRate(void)224 {225 return m_nFrameRate;226 }227 228 int CBIKMaterial::GetFrameCount(void)229 {230 return m_nFrameCount;231 }232 233 void CBIKMaterial::SetFrame(float flFrame)234 {235 U32 iFrame = (U32)flFrame + 1;236 237 if (m_pHBINK->LastFrameNum != iFrame)238 {239 BinkGoto(m_pHBINK, iFrame, 0);240 }241 }242 243 void CBIKMaterial::SetLoop(bool state)244 {245 m_bLoop = state;246 }247 248 void CBIKMaterial::CreateProceduralTexture(void)249 {250 glGenTextures(1, (GLuint *)&m_Texture);251 252 glBindTexture(GL_TEXTURE_2D, m_Texture);253 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_nBIKWidth, m_nBIKHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, m_pBuffer);254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);255 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);256 }257 258 void CBIKMaterial::DestroyProceduralTexture(void)259 {260 glDeleteTextures(1, (GLuint *)&m_Texture);261 }