Bink Player

  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 }
原文地址:https://www.cnblogs.com/crsky/p/5359632.html