Пример #1
0
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;

}
Пример #2
0
	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);
	}