Pixmap to brush?
BlitzMax Forums/MiniB3D Module/Pixmap to brush?| 
 | ||
| LoadBrush requires a path, rather than a URL for loading an image so as far as I can determine that means you need to have your images saved as files to load them. I need to be able to turn a pixmap into a brush so I poked around and came up with the following. 
Strict
Import sidesign.minib3d
Function LoadBrushPixmap:TBrush(pixmapin:TPixmap,flags=1,u_scale#=1.0,v_scale#=1.0)
	Return PixTBrush.LoadBrushPixmap(pixmapin,flags,u_scale#,v_scale#)
End Function
Function LoadTexturePixmap:TTexture(pixmapin:TPixmap,flags=1)
	Return PixTTexture.LoadTexturePixmap(pixmapin,flags)
End Function
Type PixTBrush Extends TBrush
	Function LoadBrushPixmap:TBrush(pixmapin:TPixmap,flags=1,u_scale#=1.0,v_scale#=1.0)
		Local brush:TBrush=New TBrush
		brush.tex[0]=PixTTexture.LoadTexturePixmap:TTexture(pixmapin,flags)
		brush.no_texs=1
		'brush.tex[0].u_scale#=u_scale#
		'brush.tex[0].v_scale#=v_scale#
				
		Return brush
		
	End Function
End Type
Type PixTTexture Extends TTexture
	Function LoadTexturePixMap:TTexture(pixmapin:TPixmap,flags=1,tex:TTexture=Null)
		Return LoadAnimTexturePixMap:TTexture(pixmapin,flags,0,0,0,1,tex)
	End Function
	Function LoadAnimTexturePixMap:TTexture(pixmapin:TPixmap,flags,frame_width,frame_height,first_frame,frame_count,tex:TTexture=Null)
	
		If flags&128 Then Return LoadCubeMapTexture("pixmap",flags,tex)
	
		If tex=Null Then tex:TTexture=New TTexture
		
		tex.file$="pixmap"
		tex.file_abs$="pixmap"
		
		' set tex.flags before TexInList
		tex.flags=flags
		tex.FilterFlags()
		
		' check to see if texture with same properties exists already, if so return existing texture
		Local old_tex:TTexture
		old_tex=tex.TexInList()
		If old_tex<>Null And old_tex<>tex
			Return old_tex
		Else
			If old_tex<>tex
				ListAddLast(tex_list,tex)
			EndIf
		EndIf
	
		' load pixmap
		tex.pixmap = CopyPixmap(pixmapin)
		
		' check to see if pixmap contain alpha layer, set alpha_present to true if so (do this before converting)
		Local alpha_present=False
		If tex.pixmap.format=PF_RGBA8888 Or tex.pixmap.format=PF_BGRA8888 Or tex.pixmap.format=PF_A8 Then alpha_present=True
	
		' convert pixmap to appropriate format
		If tex.pixmap.format<>PF_RGBA8888
			tex.pixmap=tex.pixmap.Convert(PF_RGBA8888)
		EndIf
		
		' if alpha flag is true and pixmap doesn't contain alpha info, apply alpha based on color values
		If tex.flags&2 And alpha_present=False
			tex.pixmap=ApplyAlpha(tex.pixmap)
		EndIf		
	
		' if mask flag is true, mask pixmap
		If tex.flags&4
			tex.pixmap=MaskPixmap(tex.pixmap,0,0,0)
		EndIf
		
		' ---
		
		' if tex not anim tex, get frame width and height
		If frame_width=0 And frame_height=0
			frame_width=tex.pixmap.width
			frame_height=tex.pixmap.height
		EndIf
	
		' ---
		
		tex.no_frames=frame_count
		tex.gltex=tex.gltex[..tex.no_frames]
	
		' ---
		
		' pixmap -> tex
	
		Local xframes=tex.pixmap.width/frame_width
		Local yframes=tex.pixmap.height/frame_height
			
		Local startx=first_frame Mod xframes
		Local starty=(first_frame/yframes) Mod yframes
			
		Local x=startx
		Local y=starty
	
		Local pixmap:TPixmap
	
		For Local i=0 To tex.no_frames-1
	
			' get static pixmap window. when resize pixmap is called new pixmap will be returned.
			pixmap=tex.pixmap.Window(x*frame_width,y*frame_height,frame_width,frame_height)
			x=x+1
			If x>=xframes
				x=0
				y=y+1
			EndIf
		
			' ---
		
			pixmap=AdjustPixmap(pixmap)
			tex.width=pixmap.width
			tex.height=pixmap.height
			Local width=pixmap.width
			Local height=pixmap.height
	
			Local name
			glGenTextures 1,Varptr name
			glBindtexture GL_TEXTURE_2D,name
	
			Local mipmap
			If tex.flags&8 Then mipmap=True
			Local mip_level=0
			Repeat
				glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format]
				glTexImage2D GL_TEXTURE_2D,mip_level,GL_RGBA8,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
				If Not mipmap Then Exit
				If width=1 And height=1 Exit
				If width>1 width:/2
				If height>1 height:/2
	
				pixmap=ResizePixmap(pixmap,width,height)
				mip_level:+1
			Forever
			tex.no_mipmaps=mip_level
	
			tex.gltex[i]=name
	
		Next
				
		Return tex
		
	End Function
End Type
which works... only once... every other brush you make is the same as the first. replacing the loadpixmap with a copypixmap and changing the pathstring to a Tpixmap was the only changes I made, but I also don't understand the nuts and bolts of what's going on here with the gl functions so I assume there's something missing between a loaded pixmap and a copy of a pixmap that makes all the difference... | 
| 
 | ||
| nevermind, I found it. seems like LoadCubeMapTexture uses the filename provided to determine if the texture already exists somewhere so it might not need to load it. Since everything was being named pixmap it thought it was already loaded. Below is a modified version that creates a fake name for the texture to force it to load, it uses the time and then a random number on the off chance the computer is fast enough to load multiple textures in a millisecond... p.s. I want that computer you can use this as an include so you don't need it dumped into your code. Strict Import sidesign.minib3d Function LoadBrushPixmap:TBrush(pixmapin:TPixmap,flags=1,u_scale#=1.0,v_scale#=1.0) Return PixTBrush.LoadBrushPixmap(pixmapin,flags,u_scale#,v_scale#) End Function Function LoadTexturePixmap:TTexture(pixmapin:TPixmap,flags=1) Return PixTTexture.LoadTexturePixmap(pixmapin,flags) End Function Type PixTBrush Extends TBrush Function LoadBrushPixmap:TBrush(pixmapin:TPixmap,flags=1,u_scale#=1.0,v_scale#=1.0) Local brush:TBrush=New TBrush brush.tex[0]=PixTTexture.LoadTexturePixmap:TTexture(pixmapin,flags) brush.no_texs=1 'brush.tex[0].u_scale#=u_scale# 'brush.tex[0].v_scale#=v_scale# Return brush End Function End Type Type PixTTexture Extends TTexture Function LoadTexturePixMap:TTexture(pixmapin:TPixmap,flags=1,tex:TTexture=Null) Return LoadAnimTexturePixMap:TTexture(pixmapin,flags,0,0,0,1,tex) End Function Function LoadAnimTexturePixMap:TTexture(pixmapin:TPixmap,flags,frame_width,frame_height,first_frame,frame_count,tex:TTexture=Null) Local pixmapFileName$ = "pixmap"+MilliSecs()+Rnd() If flags&128 Then Return LoadCubeMapTexture(pixmapFileName$,flags,tex) If tex=Null Then tex:TTexture=New TTexture tex.file$=pixmapFileName$ tex.file_abs$=pixmapFileName$ ' set tex.flags before TexInList tex.flags=flags tex.FilterFlags() ' check to see if texture with same properties exists already, if so return existing texture Local old_tex:TTexture old_tex=tex.TexInList() If old_tex<>Null And old_tex<>tex Return old_tex Else If old_tex<>tex ListAddLast(tex_list,tex) EndIf EndIf ' load pixmap tex.pixmap = CopyPixmap(pixmapin) ' check to see if pixmap contain alpha layer, set alpha_present to true if so (do this before converting) Local alpha_present=False If tex.pixmap.format=PF_RGBA8888 Or tex.pixmap.format=PF_BGRA8888 Or tex.pixmap.format=PF_A8 Then alpha_present=True ' convert pixmap to appropriate format If tex.pixmap.format<>PF_RGBA8888 tex.pixmap=tex.pixmap.Convert(PF_RGBA8888) EndIf ' if alpha flag is true and pixmap doesn't contain alpha info, apply alpha based on color values If tex.flags&2 And alpha_present=False tex.pixmap=ApplyAlpha(tex.pixmap) EndIf ' if mask flag is true, mask pixmap If tex.flags&4 tex.pixmap=MaskPixmap(tex.pixmap,0,0,0) EndIf ' --- ' if tex not anim tex, get frame width and height If frame_width=0 And frame_height=0 frame_width=tex.pixmap.width frame_height=tex.pixmap.height EndIf ' --- tex.no_frames=frame_count tex.gltex=tex.gltex[..tex.no_frames] ' --- ' pixmap -> tex Local xframes=tex.pixmap.width/frame_width Local yframes=tex.pixmap.height/frame_height Local startx=first_frame Mod xframes Local starty=(first_frame/yframes) Mod yframes Local x=startx Local y=starty Local pixmap:TPixmap For Local i=0 To tex.no_frames-1 ' get static pixmap window. when resize pixmap is called new pixmap will be returned. pixmap=tex.pixmap.Window(x*frame_width,y*frame_height,frame_width,frame_height) x=x+1 If x>=xframes x=0 y=y+1 EndIf ' --- pixmap=AdjustPixmap(pixmap) tex.width=pixmap.width tex.height=pixmap.height Local width=pixmap.width Local height=pixmap.height Local name glGenTextures 1,Varptr name glBindtexture GL_TEXTURE_2D,name Local mipmap If tex.flags&8 Then mipmap=True Local mip_level=0 Repeat glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format] glTexImage2D GL_TEXTURE_2D,mip_level,GL_RGBA8,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels If Not mipmap Then Exit If width=1 And height=1 Exit If width>1 width:/2 If height>1 height:/2 pixmap=ResizePixmap(pixmap,width,height) mip_level:+1 Forever tex.no_mipmaps=mip_level tex.gltex[i]=name Next Return tex End Function End Type | 
| 
 | ||
| I'm using this function excessively, thanks for that. But I have a small improvement - your function does not clear the tex.pixmap after loading which causes a memory leak each time you load the same pixmap again and again. So I had to add "tex.pixmap = Null" at the end before returning the tex to fix it. Here my corrected function: |