@@ -212,71 +212,182 @@ char* cgeGetScaledBufferInSize(const void* buffer, int& w, int& h, int channel,
212212
213213// ///////////////////////////////////////////////
214214
215- SharedTexture::SharedTexture (GLuint textureID, int w, int h)
215+ TextureObject::TextureObject (GLuint texture, const CGESizei& size) :
216+ m_texture (texture), m_size (size)
216217{
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 );
227228}
228229
229- SharedTexture ::~SharedTexture ()
230+ TextureObject ::~TextureObject ()
230231{
231- if (m_refCount == nullptr )
232+ if (m_texture != 0 )
232233 {
233- CGE_LOG_CODE (
234- if (m_textureID != 0 ) {
235- CGE_LOG_ERROR (" SharedTexture : Error occurred!" );
236- });
237- return ;
234+ cleanup (true );
238235 }
236+ }
239237
240- --*m_refCount;
241- if (*m_refCount <= 0 )
238+ TextureObject& TextureObject::operator =(TextureObject&& t) noexcept
239+ {
240+ if (this == &t)
242241 {
243- clear () ;
242+ return * this ;
244243 }
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 ;
249248}
250249
251- void SharedTexture::forceRelease ( bool bDelTexture )
250+ TextureObject& TextureObject:: operator =(TextureInfo&& t )
252251{
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 ;
262256}
263257
264- void SharedTexture::clear ( )
258+ void TextureObject::cleanup ( bool deleteTexture )
265259{
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+ }
272268
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+ }
274278
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+ }
277299
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 ;
281323}
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+
282393} // namespace CGE
0 commit comments