@@ -212,71 +212,182 @@ char* cgeGetScaledBufferInSize(const void* buffer, int& w, int& h, int channel,
212
212
213
213
// ///////////////////////////////////////////////
214
214
215
- SharedTexture::SharedTexture (GLuint textureID, int w, int h)
215
+ TextureObject::TextureObject (GLuint texture, const CGESizei& size) :
216
+ m_texture (texture), m_size (size)
216
217
{
217
- m_textureID = textureID;
218
- m_refCount = new int ( 1 );
219
- width = w ;
220
- height = h;
221
- CGE_LOG_CODE (
222
- if (m_textureID == 0 )
223
- CGE_LOG_ERROR ( " CGESharedTexture : Invalid TextureID! " );
224
- else {
225
- CGE_LOG_INFO ( " ---CGESharedTexture creating, textureID %d, total : %d ### \n " , textureID, ++ sTextureCount );
226
- } );
218
+ if (texture == 0 && size. width != 0 && size. height != 0 )
219
+ {
220
+ resize (size. width , size. height ) ;
221
+ }
222
+ }
223
+
224
+ TextureObject::TextureObject (TextureObject&& t) noexcept :
225
+ m_texture (t. texture ()), m_size (t. size ())
226
+ {
227
+ t. cleanup ( false );
227
228
}
228
229
229
- SharedTexture ::~SharedTexture ()
230
+ TextureObject ::~TextureObject ()
230
231
{
231
- if (m_refCount == nullptr )
232
+ if (m_texture != 0 )
232
233
{
233
- CGE_LOG_CODE (
234
- if (m_textureID != 0 ) {
235
- CGE_LOG_ERROR (" SharedTexture : Error occurred!" );
236
- });
237
- return ;
234
+ cleanup (true );
238
235
}
236
+ }
239
237
240
- --*m_refCount;
241
- if (*m_refCount <= 0 )
238
+ TextureObject& TextureObject::operator =(TextureObject&& t) noexcept
239
+ {
240
+ if (this == &t)
242
241
{
243
- clear () ;
242
+ return * this ;
244
243
}
245
- CGE_LOG_CODE (
246
- else {
247
- CGE_LOG_INFO ( " @@@ Texture %d deRef count: %d \n " , m_textureID, *m_refCount );
248
- })
244
+ m_texture = t. texture ();
245
+ m_size = t. size ();
246
+ t. cleanup ( false );
247
+ return * this ;
249
248
}
250
249
251
- void SharedTexture::forceRelease ( bool bDelTexture )
250
+ TextureObject& TextureObject:: operator =(TextureInfo&& t )
252
251
{
253
- assert (m_refCount == nullptr || *m_refCount == 1 ); // 使用 forceRelease 时 SharedTexture 必须保证只存在一个实例
254
- if (bDelTexture)
255
- glDeleteTextures (1 , &m_textureID);
256
- m_textureID = 0 ;
257
- CGE_DELETE (m_refCount);
258
- width = 0 ;
259
- height = 0 ;
260
- CGE_LOG_CODE (
261
- --sTextureCount ;);
252
+ m_texture = t.name ;
253
+ m_size = { t.width , t.height };
254
+ t.name = 0 ;
255
+ return *this ;
262
256
}
263
257
264
- void SharedTexture::clear ( )
258
+ void TextureObject::cleanup ( bool deleteTexture )
265
259
{
266
- CGE_LOG_CODE (
267
- if (m_textureID == 0 ) {
268
- CGE_LOG_ERROR (" !!!CGESharedTexture - Invalid TextureID To Release!\n " );
269
- } else {
270
- CGE_LOG_INFO (" ###CGESharedTexture deleting, textureID %d, now total : %d ###\n " , m_textureID, --sTextureCount );
271
- });
260
+ if (deleteTexture && m_texture != 0 )
261
+ {
262
+ assert (glIsTexture (m_texture));
263
+ CGE_DELETE_GL_OBJS (glDeleteTextures, m_texture);
264
+ }
265
+ m_texture = 0 ;
266
+ m_size.set (0 , 0 );
267
+ }
272
268
273
- assert (*m_refCount == 0 ); // 未知错误
269
+ bool TextureObject::resize (int w, int h, const void * buffer, GLenum format)
270
+ {
271
+ if (m_texture == 0 || m_size.width != w || m_size.height != h || buffer != nullptr )
272
+ {
273
+ if (w == 0 || h == 0 )
274
+ {
275
+ assert (0 && " TextureObject::resize must not be 0!" );
276
+ return false ;
277
+ }
274
278
275
- glDeleteTextures (1 , &m_textureID);
276
- m_textureID = 0 ;
279
+ int channel;
280
+ switch (format)
281
+ {
282
+ case GL_LUMINANCE:
283
+ channel = 1 ;
284
+ break ;
285
+ case GL_LUMINANCE_ALPHA:
286
+ channel = 2 ;
287
+ break ;
288
+ case GL_RGB:
289
+ channel = 3 ;
290
+ break ;
291
+ case GL_RGBA:
292
+ channel = 4 ;
293
+ break ;
294
+ default :
295
+ assert (0 );
296
+ channel = 4 ;
297
+ break ;
298
+ }
277
299
278
- CGE_DELETE (m_refCount);
279
- width = 0 ;
280
- height = 0 ;
300
+ if (m_texture == 0 )
301
+ {
302
+ m_texture = cgeGenTextureWithBuffer (buffer, w, h, format, GL_UNSIGNED_BYTE, channel);
303
+ m_size.set (w, h);
304
+ }
305
+ else
306
+ {
307
+ glBindTexture (GL_TEXTURE_2D, m_texture);
308
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1 );
309
+ if (m_size.width != w || m_size.height != h)
310
+ {
311
+ m_size.set (w, h);
312
+ glTexImage2D (GL_TEXTURE_2D, 0 , format, w, h, 0 , format, GL_UNSIGNED_BYTE, buffer);
313
+ }
314
+ else
315
+ {
316
+ glTexSubImage2D (GL_TEXTURE_2D, 0 , 0 , 0 , w, h, format, GL_UNSIGNED_BYTE, buffer);
317
+ }
318
+ }
319
+
320
+ return true ;
321
+ }
322
+ return false ;
281
323
}
324
+
325
+ // ////////////
326
+
327
+ FrameBufferWithTexture::~FrameBufferWithTexture ()
328
+ {
329
+ if (m_renderBuffer != 0 )
330
+ {
331
+ CGE_DELETE_GL_OBJS (glDeleteRenderbuffers, m_renderBuffer);
332
+ }
333
+ }
334
+
335
+ void FrameBufferWithTexture::bindTexture2D (GLsizei w, GLsizei h, const void * buffer)
336
+ {
337
+ if (resize (w, h, buffer))
338
+ {
339
+ FrameBuffer::bindTexture2D (m_texture);
340
+
341
+ // auto resize renderbuffer if exist.
342
+ if (m_renderBuffer != 0 )
343
+ {
344
+ attachDepthBuffer ();
345
+ }
346
+ assert (checkStatus ());
347
+ }
348
+ else
349
+ {
350
+ FrameBuffer::bind ();
351
+ }
352
+ }
353
+
354
+ void FrameBufferWithTexture::attachDepthBuffer ()
355
+ {
356
+ bool shouldCreate = false ;
357
+
358
+ if (m_renderBuffer == 0 )
359
+ {
360
+ shouldCreate = true ;
361
+ }
362
+ else
363
+ {
364
+ GLint param[2 ] = { 0 , 0 };
365
+ glBindRenderbuffer (GL_RENDERBUFFER, m_renderBuffer);
366
+ glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, param);
367
+ glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, param + 1 );
368
+ shouldCreate = (param[0 ] != m_size.width || param[1 ] != m_size.height );
369
+ }
370
+
371
+ if (shouldCreate)
372
+ {
373
+ if (m_renderBuffer == 0 )
374
+ glGenRenderbuffers (1 , &m_renderBuffer);
375
+
376
+ glBindFramebuffer (GL_FRAMEBUFFER, m_framebuffer);
377
+ glBindRenderbuffer (GL_RENDERBUFFER, m_renderBuffer);
378
+ glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_size.width , m_size.height );
379
+ glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_renderBuffer);
380
+ }
381
+ }
382
+
383
+ bool FrameBufferWithTexture::checkStatus ()
384
+ {
385
+ GLenum ret = glCheckFramebufferStatus (GL_FRAMEBUFFER);
386
+ if (ret != GL_FRAMEBUFFER_COMPLETE)
387
+ {
388
+ CGE_LOG_ERROR (" Frame buffer incomplete: %x!\n " , ret);
389
+ }
390
+ return ret == GL_FRAMEBUFFER_COMPLETE;
391
+ }
392
+
282
393
} // namespace CGE
0 commit comments