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 }