SDL_Surface* pow2img(SDL_Surface *src) { if(ISPOW2(src->w) && ISPOW2(src->h)) return src; SDL_SetAlpha(src, 0, SDL_ALPHA_OPAQUE); SDL_Surface *dst = NULL; dst = SDL_CreateRGBSurface(src->flags, topow2(src->w), topow2(src->h), src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); if(!dst || SDL_BlitSurface(src, NULL, dst, NULL)) { SDL_FreeSurface(dst); return NULL; } return dst; }
OGL2DTexture::OGL2DTexture(OGLDevice& ogldevice,const base::String& identifier, const ion_uint32 width,const ion_uint32 height,const ion_uint32 levels,const ion_uint32 flags,const video::Pixelformat format, const video::Memorypool pool):video::Texture2D(format,identifier,flags),m_rOGLDevice(ogldevice),m_IsValid(true), m_IsDataOK(true),m_IsMapped(false),m_GLHandle(0),m_Framebuffer(0),m_DepthRenderbuffer(0), m_StencilRenderbuffer(0),m_LevelWidth(0),m_LevelHeight(0),m_MappedLevel(0),m_CurrentLevel(0xffffffff)/*, m_Picbuffer(width,height,ogl2dtexformat(format))*/ { if (!video::isDepthformat(format)) { glGenTextures(1,&m_GLHandle); } m_pSurfaces=0; m_OGLTexture.target(GL_TEXTURE_2D); m_OGLTexture.handle(m_GLHandle); ion_uint32 actualwidth=width,actualheight=height; if (!ISPOW2(actualwidth)) actualwidth=nextpow2(actualwidth); if (!ISPOW2(actualheight)) actualheight=nextpow2(actualheight); if (actualwidth!=actualheight) { ion_uint32 i=(actualwidth>actualheight) ? actualwidth : actualheight; actualwidth=actualheight=i; } m_pPicbuffer= ::new video::SimplePicbuffer(actualwidth,actualheight,ogl2dtexformat(format)); m_Width=actualwidth; m_Height=actualheight; m_Pixelformat=m_pPicbuffer->pixelformat(); m_NumMipmaplevels=levels; m_Internalformat=oglpixelformat(format); if (ogldevice.extensionSupported("GL_EXT_framebuffer_object")) { if (video::isDepthformat(format)) { if (ogldevice.extensionSupported("GL_ARB_depth_texture")) { GLenum depthformat=GL_DEPTH_COMPONENT24_ARB; switch (format) { case video::Pixelformat_D15S1: case video::Pixelformat_D16: depthformat=GL_DEPTH_COMPONENT16_ARB; break; case video::Pixelformat_D24: case video::Pixelformat_D24S4: case video::Pixelformat_D24S8: case video::Pixelformat_FD24S8: depthformat=GL_DEPTH_COMPONENT24_ARB; break; case video::Pixelformat_D32: depthformat=GL_DEPTH_COMPONENT32_ARB; break; default:break; } // TODO: depthstencil formats glGenRenderbuffersEXT(1,&m_DepthRenderbuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,m_DepthRenderbuffer); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT24_ARB,width,height); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,0); m_NumMipmaplevels=1; m_pSurfaces=new OGL2DSurface[1]; m_pSurfaces[0].m_pOGL2DTexture=this; m_pSurfaces[0].m_pTexture=this; m_pSurfaces[0].m_Level=0; m_pSurfaces[0].m_GLHandle=0; m_pSurfaces[0].m_Width=actualwidth; m_pSurfaces[0].m_Height=actualheight; m_pSurfaces[0].m_DepthRenderbuffer=m_DepthRenderbuffer; m_pSurfaces[0].m_Framebuffer=0; m_pSurfaces[0].m_StencilRenderbuffer=0; } else m_IsValid=false; } else if (flags&video::Textureflag_IsRendertaget) { glGenFramebuffersEXT(1,&m_Framebuffer); glBindTexture(GL_TEXTURE_2D,m_GLHandle); // TODO: Save bound textures and restore them afterwards GLenum format=oglrgbaformat(video::rgbalayoutFromPixelformat(m_Pixelformat)); GLenum type=GL_UNSIGNED_BYTE; // TODO m_NumMipmaplevels=1; // TODO: Support mipmaps in rendertargets m_pSurfaces=new OGL2DSurface[1]; m_pSurfaces[0].m_pOGL2DTexture=this; m_pSurfaces[0].m_pTexture=this; m_pSurfaces[0].m_Level=0; m_pSurfaces[0].m_GLHandle=m_GLHandle; m_pSurfaces[0].m_Width=actualwidth; m_pSurfaces[0].m_Height=actualheight; m_pSurfaces[0].m_DepthRenderbuffer=0; m_pSurfaces[0].m_Framebuffer=m_Framebuffer; m_pSurfaces[0].m_StencilRenderbuffer=0; glTexImage2D(GL_TEXTURE_2D,0,m_Internalformat,width,height,0,format,type,0); glBindTexture(GL_TEXTURE_2D,0); } } else if (video::isDepthformat(format) || (flags&video::Textureflag_IsRendertaget)) { m_IsValid=false; } if (m_GLHandle!=0) { glbind(); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,(levels==1) ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); if (levels>1) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,levels-1); } if (m_NumMipmaplevels==0) { ion_uint32 length=(actualwidth<actualheight) ? actualwidth : actualheight; if (length<=1) m_NumMipmaplevels=1; else { m_NumMipmaplevels=((ion_uint32)( logf((float)length)/logf(2.0f) )) + 1; } } m_OGLTexture.numLevels(m_NumMipmaplevels); m_pDataSubmitted=new bool[m_NumMipmaplevels]; for (ion_uint32 lvl=0;lvl<m_NumMipmaplevels;++lvl) m_pDataSubmitted[lvl]=false; currentLevel(0); }