Texture on a cube

BlitzMax Modules Forums/MiniB3D/Texture on a cube

This should be simple. Can anyone give me a short example of how to give every side of a cube a different (image) texture? Like drawing a die.
I'm searching the community for two days now but I can't find an example showing this. I'm still working on my rotating postcard (see: http://www.blitzbasic.com/Community/posts.php?topic=69542)

Create a cube yourself in code using CreateMesh->CreateSurface->AddVertex->AddTriangle. Make sure you have four vertices per side.

Now, create one texture with six square images packed inside. Now you just need to use VertexTexCoords to set the texture coordinates for each side so that the correct square from the texture is displayed.

Alternatively create a mesh with six surfaces (one side per surface), create six separate textures, and use PaintSurface to texture each side individually. This is less efficient than the above method though.

I was hoping to hear a easier solution :(
Anyway, I'll try both methods.
Thanx

I would model and texture a the cube and then load the mesh personaly, but then it becomes difficult to change the faces later if that's what you need to do..

ima747> My question was how to do this in runtime.

At the moment I have a nice demo for the project I'm working on. Since everything I do here is (strictly) confidential, I can't show the result as it is now. I'm thinking about making something that is not classified, cos I think this (+ the rotating thing) can be handy for others as well.

Here is an example of the second sugestion of simonh.
It works fine for the creation of the cube. I can also color each surface with a RGB brush. But I can't get an image on a surface. Am I missing something?

SuperStrict

Import klepto.minib3d

Graphics3D 800 , 600 , 32	
AmbientLight(255, 255, 255)

HideMouse()
'camera and light
Local  cam:tCamera = CreateCamera()		'<=  create the camera
cam.PositionEntity (0,-4, 0)				'<= position the camera
Local light:tlight = CreateLight()		'<= create light for the scene
PositionEntity light, 0, -1, 0

Local cube:TCube = TCube.create(0, 0, 0, 1, 1, 0.1)
'here I'll change the front surface of the cube to an image texture
cube.setTexture(2, "gfx/picture.png")
'but nothing happens (well, the surface becomes a little bit darker grey...?)

PointEntity(cam, cube.poPivot)

Global MoveX#, MoveY#			'<= Move function globals

Repeat
'	BrushColor(cube.poBrushes[2], Rand(255), Rand(255), Rand(255))		'Changing the brush seems to work for RGB colors

	move(cube.poCube, 0.4,0.1)  '<=change this values for speed and sensibility
	RenderWorld
	text 20,20, "Use Key UP/DOWN and mouse"
	Flip
	Delay 20
Until KeyHit(KEY_ESCAPE) 

ShowMouse()
End



Function Move(M_plane:TMesh,vel:Float=1,spd:Float)
	If KeyDown(KEY_UP) Then M_plane.MoveEntity 0 , 0 , vel
	If KeyDown(KEY_DOWN) Then M_plane.MoveEntity 0 , 0 , -vel
	
	
	Local pitch#,yaw#
	MoveX# = ((TBlitz2D.MouseXSpeed() - MoveX#) * spd + MoveX#) * .5
	MoveY# = ((TBlitz2D.MouseYSpeed() - MoveY#) * spd + MoveY#) * .5

	pitch# = EntityPitch(M_plane) - MoveY#
	yaw# = - MoveX# + EntityYaw(M_plane)
	
	RotateEntity M_plane, pitch#, yaw#, 0	
	MoveMouse GraphicsWidth() / 2 , GraphicsHeight() / 2 'keep the mouse centered
	
	TBlitz2D.MouseXSpeed()  ' To flush MouseXSpeed
	TBlitz2D.MouseySpeed()
	
End Function


Type TCube
	Field poPivot:TPivot = CreatePivot()
	Field poCube:TMesh
	Field pfWidth#
	Field pfHeight#
	Field pfDepth#
	Field poBrushes:TBrush[6]
	Field poSurfaces:TSurface[6]
	
	Function create:TCube(x# = 0, y# = 0, z# = 0, w# = 1, h# = 1, d# = 1)
		Local c:TCube = New TCube
		PositionEntity(c.poPivot, x, y, z)
		c.pfWidth = w
		c.pfHeight = h
		c.pfDepth = d
		
		c.poCube = CreateMesh(c.poPivot)
		For Local i% = 0 To 5
			c.poBrushes[i] = CreateBrush(200, 200, 200)
			BrushShininess(c.poBrushes[i], 0.75)
			c.poSurfaces[i] = CreateSurface(c.poCube)
			PaintSurface(c.poSurfaces[i], c.poBrushes[i])
		Next
		
		Local v0%, v1%, v2%, v3%, t0%, t1%
		'bottom
		v0 = AddVertex(c.poSurfaces[0],-0.5,-0.5,-0.5)
		v1 = AddVertex(c.poSurfaces[0],-0.5,-0.5,0.5)
		v2 = AddVertex(c.poSurfaces[0],0.5,-0.5,0.5)
		v3 = AddVertex(c.poSurfaces[0],0.5,-0.5,-0.5)
		
		t0 = AddTriangle(c.poSurfaces[0], v0, v3, v2)
		t1 = AddTriangle(c.poSurfaces[0], v0, v2, v1)
		
		'top
		v0 = AddVertex(c.poSurfaces[1],-0.5,0.5,-0.5)
		v1 = AddVertex(c.poSurfaces[1],-0.5,0.5,0.5)
		v2 = AddVertex(c.poSurfaces[1],0.5,0.5,0.5)
		v3 = AddVertex(c.poSurfaces[1],0.5,0.5,-0.5)
		
		t0 = AddTriangle(c.poSurfaces[1], v0, v1, v2)
		t1 = AddTriangle(c.poSurfaces[1], v0, v2, v3)
				
		'front
		v0 = AddVertex(c.poSurfaces[2],-0.5,-0.5,-0.5)
		v1 = AddVertex(c.poSurfaces[2],0.5,-0.5,-0.5)
		v2 = AddVertex(c.poSurfaces[2],0.5,0.5,-0.5)
		v3 = AddVertex(c.poSurfaces[2],-0.5,0.5,-0.5)
		
		t0 = AddTriangle(c.poSurfaces[2], v0, v3, v2)
		t1 = AddTriangle(c.poSurfaces[2], v0, v2, v1)
		
		'back
		v0 = AddVertex(c.poSurfaces[3],0.5,-0.5,0.5)
		v1 = AddVertex(c.poSurfaces[3],-0.5,-0.5,0.5)
		v2 = AddVertex(c.poSurfaces[3],-0.5,0.5,0.5)
		v3 = AddVertex(c.poSurfaces[3],0.5,0.5,0.5)
		
		t0 = AddTriangle(c.poSurfaces[3], v0, v3, v2)
		t1 = AddTriangle(c.poSurfaces[3], v0, v2, v1)
		
		'left
		v0 = AddVertex(c.poSurfaces[4],-0.5,-0.5,0.5)
		v1 = AddVertex(c.poSurfaces[4],-0.5,-0.5,-0.5)
		v2 = AddVertex(c.poSurfaces[4],-0.5,0.5,-0.5)
		v3 = AddVertex(c.poSurfaces[4],-0.5,0.5,0.5)
		
		t0 = AddTriangle(c.poSurfaces[4], v0, v3, v2)
		t1 = AddTriangle(c.poSurfaces[4], v0, v2, v1)
				
		'right
		v0 = AddVertex(c.poSurfaces[5],0.5,-0.5,-0.5)
		v1 = AddVertex(c.poSurfaces[5],0.5,-0.5,0.5)
		v2 = AddVertex(c.poSurfaces[5],0.5,0.5,0.5)
		v3 = AddVertex(c.poSurfaces[5],0.5,0.5,-0.5)
		
		t0 = AddTriangle(c.poSurfaces[5], v0, v3, v2)
		t1 = AddTriangle(c.poSurfaces[5], v0, v2, v1)
		
		ScaleEntity(c.poCube, w, h, d)
		Return c
	End Function


	Method setTexture(iSurface%, fn$)
		Local tex:TTexture = LoadTexture(fn)
		BrushTexture(poBrushes[iSurface], tex)
		PaintSurface(poSurfaces[iSurface], poBrushes[iSurface])   'is this necessary?
	End Method
	
End Type


Indeed you have missed something ;)

Your Surfaces have no UV Coords for your texture.
This should work:

SuperStrict

Import klepto.minib3d

Graphics3D 800 , 600 , 32	
AmbientLight(255, 255, 255)

HideMouse()
'camera and light
Local  cam:tCamera = CreateCamera()		'<=  create the camera
cam.PositionEntity (0,-4, 0)				'<= position the camera
Local light:tlight = CreateLight()		'<= create light for the scene
PositionEntity light, 0, -1, 0

Local cube:TCube = TCube.create(0, 0, 0, 1, 1, 0.1)
'here I'll change the front surface of the cube to an image texture
cube.setTexture(2 , "D:\test.bmp")
cube.setTexture(0 , "D:\test.bmp")
cube.setTexture(1, "D:\test.bmp")
cube.setTexture(3, "D:\test.bmp")
cube.setTexture(4, "D:\test.bmp")
cube.setTexture(5, "D:\test.bmp")

'but nothing happens (well, the surface becomes a little bit darker grey...?)

PointEntity(cam, cube.poPivot)

Global MoveX#, MoveY#			'<= Move function globals

Repeat
'	BrushColor(cube.poBrushes[2], Rand(255), Rand(255), Rand(255))		'Changing the brush seems to work for RGB colors

	move(cube.poCube, 0.4,0.1)  '<=change this values for speed and sensibility
	RenderWorld
	text 20,20, "Use Key UP/DOWN and mouse"
	Flip
	Delay 20
Until KeyHit(KEY_ESCAPE) 

ShowMouse()
End



Function Move(M_plane:TMesh,vel:Float=1,spd:Float)
	If KeyDown(KEY_UP) Then M_plane.MoveEntity 0 , 0 , vel
	If KeyDown(KEY_DOWN) Then M_plane.MoveEntity 0 , 0 , -vel
	
	
	Local pitch#,yaw#
	MoveX# = ((TBlitz2D.MouseXSpeed() - MoveX#) * spd + MoveX#) * .5
	MoveY# = ((TBlitz2D.MouseYSpeed() - MoveY#) * spd + MoveY#) * .5

	pitch# = EntityPitch(M_plane) - MoveY#
	yaw# = - MoveX# + EntityYaw(M_plane)
	
	RotateEntity M_plane, pitch#, yaw#, 0	
	MoveMouse GraphicsWidth() / 2 , GraphicsHeight() / 2 'keep the mouse centered
	
	TBlitz2D.MouseXSpeed()  ' To flush MouseXSpeed
	TBlitz2D.MouseySpeed()
	
End Function


Type TCube
	Field poPivot:TPivot = CreatePivot()
	Field poCube:TMesh
	Field pfWidth#
	Field pfHeight#
	Field pfDepth#
	Field poBrushes:TBrush[6]
	Field poSurfaces:TSurface[6]
	
	Function create:TCube(x# = 0, y# = 0, z# = 0, w# = 1, h# = 1, d# = 1)
		Local c:TCube = New TCube
		PositionEntity(c.poPivot, x, y, z)
		c.pfWidth = w
		c.pfHeight = h
		c.pfDepth = d
		
		c.poCube = CreateMesh(c.poPivot)
		For Local i% = 0 To 5
			c.poBrushes[i] = CreateBrush(200, 200, 200)
			BrushShininess(c.poBrushes[i], 0.75)
			c.poSurfaces[i] = CreateSurface(c.poCube)
			PaintSurface(c.poSurfaces[i], c.poBrushes[i])
		Next
		
		Local v0%, v1%, v2%, v3%, t0%, t1%
		'bottom
		v0 = AddVertex(c.poSurfaces[0],-0.5,-0.5,-0.5,0,0)
		v1 = AddVertex(c.poSurfaces[0],-0.5,-0.5,0.5,0,1)
		v2 = AddVertex(c.poSurfaces[0],0.5,-0.5,0.5,1,0)
		v3 = AddVertex(c.poSurfaces[0],0.5,-0.5,-0.5,1,1)
		
		t0 = AddTriangle(c.poSurfaces[0], v0, v3, v2)
		t1 = AddTriangle(c.poSurfaces[0], v0, v2, v1)
		
		'top
		v0 = AddVertex(c.poSurfaces[1],-0.5,0.5,-0.5,0,0)
		v1 = AddVertex(c.poSurfaces[1],-0.5,0.5,0.5,0,1)
		v2 = AddVertex(c.poSurfaces[1],0.5,0.5,0.5,1,0)
		v3 = AddVertex(c.poSurfaces[1],0.5,0.5,-0.5,1,1)
		
		t0 = AddTriangle(c.poSurfaces[1], v0, v1, v2)
		t1 = AddTriangle(c.poSurfaces[1], v0, v2, v3)
				
		'front
		v0 = AddVertex(c.poSurfaces[2],-0.5,-0.5,-0.5,0,0)
		v1 = AddVertex(c.poSurfaces[2],0.5,-0.5,-0.5,0,1)
		v2 = AddVertex(c.poSurfaces[2],0.5,0.5,-0.5,1,0)
		v3 = AddVertex(c.poSurfaces[2],-0.5,0.5,-0.5,1,1)
		
		t0 = AddTriangle(c.poSurfaces[2], v0, v3, v2)
		t1 = AddTriangle(c.poSurfaces[2], v0, v2, v1)
		
		'back
		v0 = AddVertex(c.poSurfaces[3],0.5,-0.5,0.5,0,0)
		v1 = AddVertex(c.poSurfaces[3],-0.5,-0.5,0.5,0,1)
		v2 = AddVertex(c.poSurfaces[3],-0.5,0.5,0.5,1,0)
		v3 = AddVertex(c.poSurfaces[3],0.5,0.5,0.5,1,1)
		
		t0 = AddTriangle(c.poSurfaces[3], v0, v3, v2)
		t1 = AddTriangle(c.poSurfaces[3], v0, v2, v1)
		
		'left
		v0 = AddVertex(c.poSurfaces[4],-0.5,-0.5,0.5,0,0)
		v1 = AddVertex(c.poSurfaces[4],-0.5,-0.5,-0.5,0,1)
		v2 = AddVertex(c.poSurfaces[4],-0.5,0.5,-0.5,1,0)
		v3 = AddVertex(c.poSurfaces[4],-0.5,0.5,0.5,1,1)
		
		t0 = AddTriangle(c.poSurfaces[4], v0, v3, v2)
		t1 = AddTriangle(c.poSurfaces[4], v0, v2, v1)
				
		'right
		v0 = AddVertex(c.poSurfaces[5],0.5,-0.5,-0.5,0,0)
		v1 = AddVertex(c.poSurfaces[5],0.5,-0.5,0.5,0,1)
		v2 = AddVertex(c.poSurfaces[5],0.5,0.5,0.5,1,0)
		v3 = AddVertex(c.poSurfaces[5],0.5,0.5,-0.5,1,1)
		
		t0 = AddTriangle(c.poSurfaces[5], v0, v3, v2)
		t1 = AddTriangle(c.poSurfaces[5], v0, v2, v1)
		
		ScaleEntity(c.poCube, w, h, d)
		Return c
	End Function


	Method setTexture(iSurface%, fn$)
		Local tex:TTexture = LoadTexture(fn)
		BrushTexture(poBrushes[iSurface], tex)
		PaintSurface(poSurfaces[iSurface], poBrushes[iSurface])   'is this necessary?
	End Method
	
End Type


Take a closer look to the additional parameters in the AddVertex function.

Theses describes the uv coordinates:

TopLeft-------------TopRight
--------o,o******1,0
-----------*------*
-----------*------*
-----------*------*
--------0,1******1,1
BottomLeft----------BottomRight

Thanks for the help.
Implemented and tested your uv coordinates. Had to rearrange the order a little (0,0 - 0,1 - 1,0 - 1,1 has become 0,0 - 0,1 - 1,1 - 1,0). Now it works fine. Have to look at this closer. I do not really understand this uv-stuff, but I'll have a closer look at it.
Anyway, I have this nice cube on which I can attach a texture on each side in run-time.

If I want to create a texture not by using loadTexture(url$) but by using an image (or a pixmap); something like createTexture(img:TImage) do I have to modify your TTexture.bmx file or should I make a child type like:
TmyTexture extends TTexture
and make my own creation method? Or is there another way?
For my project I already have the required images stored in a field, so it's not desirable to have to file-load these images again for the textures.

Yes, there is another way ;)

Use my modified (partly 0.42 ext) TTexture.bmx and recompile
the module.

TTexture.bmx
' Updates:
' 30/01/07 - AdjustPixmap

Type TTexture

	Global tex_list:TList=CreateList()

	Field file$,flags,blend=2,coords,u_scale#=1.0,v_scale#=1.0,u_pos#,v_pos#,angle#
	Field file_abs$,width,height ' returned by Name/Width/Height commands
	Field pixmap:TPixmap
	Field gltex[1]
	Field cube_pixmap:TPixmap[7]
	Field no_frames=1
	Field no_mipmaps
	Field cube_face=0,cube_mode=1
	
	Method FreeTexture()
	
		ListRemove(tex_list,Self)
		pixmap=Null
		cube_pixmap=Null
		gltex=Null
	
	End Method
	
	Function CreateTexture:TTexture(width,height,flags=1,frames=1,RenderTarget:Int = GL_RGBA)
	
		If flags&128 Then Return CreateCubeMapTexture(width,height,flags)
	
		Local tex:TTexture=New TTexture
		
		tex.pixmap=CreatePixmap(width*frames,height,PF_RGBA8888)

		' ***
		
		tex.flags=flags
		tex.FilterFlags()
				
		tex.no_frames=frames
		tex.gltex=tex.gltex[..tex.no_frames]

		' ***
		
		' pixmap -> tex
			
		Local x=0
	
		Local pixmap:TPixmap
	
		For Local i=0 To tex.no_frames-1
	
			pixmap=tex.pixmap.Window(x*width,0,width,height)
			x=x+1
		
			' ***
		
			pixmap=AdjustPixmap(pixmap)
			tex.width=pixmap.width
			tex.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
			
			Local Internal:Int
				Select RenderTarget
					Case GL_RGBA
						Internal = GL_RGBA8
					Case GL_DEPTH_COMPONENT
						Internal = GL_DEPTH_COMPONENT
				End Select
			Repeat
				glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format]
				glTexImage2D GL_TEXTURE_2D,mip_level,Internal,tex.width,tex.height,0,RenderTarget,GL_UNSIGNED_BYTE,pixmap.pixels
				If Not mipmap Then Exit
				If tex.width=1 And tex.height=1 Exit
				If tex.width>1 tex.width:/2
				If tex.height>1 tex.height:/2

				pixmap=ResizePixmap(pixmap,tex.width,tex.height)
				mip_level:+1
			Forever
			tex.no_mipmaps=mip_level

			tex.gltex[i]=Name
	
		Next
		
		ListAddLast(tex_list,tex)
	
		Return tex

	End Function

	Function LoadTexture:TTexture(file:Object,flags=1)
	
		Return LoadAnimTexture:TTexture(file,flags,0,0,0,1)
	
	End Function
	
	Function LoadAnimTexture:TTexture(file2:Object,flags,frame_width,frame_height,first_frame,frame_count)
		Local file:Object = file2
		If flags&128 Then Return LoadCubeMapTexture(file,flags)

		Local tex:TTexture = New TTexture
		
		'()
		'DebugStop()
		file = Filefind(String(file))
		If File = Null Then 
			If TImage(file2) <> Null Then
				tex.file$="image"+tex_list.count()
				tex.file_abs$="//"
				
				' set tex.flags before TexInList
				tex.flags=flags
				tex.FilterFlags()
				
				Local old_tex:TTexture
				old_tex=tex.TexInList()
				If old_tex<>Null Then Return old_tex
		
				' load pixmap
				tex.pixmap = LockImage(TImage(file2) )
			ElseIf TPixmap(file2) <> Null Then
				tex.file$="pixmap"+tex_list.count()
				tex.file_abs$="//"
				
				' set tex.flags before TexInList
				tex.flags=flags
				tex.FilterFlags()
				
				Local old_tex:TTexture
				old_tex=tex.TexInList()
				If old_tex<>Null Then Return old_tex
		
				' load pixmap
				tex.pixmap = TPixmap(file2)
			Else
				Return Null
			EndIf
		Else
		
		'If FileFind(file)=False Then Return Null
		
			tex.file$=String(file)
			tex.file_abs$=FileAbs$(String(file))
			
			' set tex.flags before TexInList
			tex.flags=flags
			tex.FilterFlags()
			
			Local old_tex:TTexture
			old_tex=tex.TexInList()
			If old_tex<>Null Then Return old_tex
	
			' load pixmap
			tex.pixmap = LoadPixmap(file)
		EndIf
		
		If tex.pixmap = Null Then Return
		' convert pixmap to appropriate format
		If tex.pixmap.format<>PF_RGBA8888
			tex.pixmap=tex.pixmap.Convert(PF_RGBA8888)
		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.flags=flags
		'tex.FilterFlags()
		
		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 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,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
				If Not mipmap Then Exit
				If tex.width=1 And tex.height=1 Exit
				If tex.width>1 tex.width:/2
				If tex.height>1 tex.height:/2

				pixmap=ResizePixmap(pixmap,tex.width,tex.height)
				mip_level:+1
			Forever
			tex.no_mipmaps=mip_level

			tex.gltex[i]=Name
	
		Next
		
		ListAddLast(tex_list,tex)
		TGlobal.Errorhandler.CheckError("TTextrue.bmx",204)
	   	TGlobal.ErrorHandler.SendMsg("texture '"+String(file)+" succesfully loaded")

		Return tex
		
	End Function

	Function CreateCubeMapTexture:TTexture(width,height,flags)

		Local tex:TTexture=New TTexture
		
		tex.pixmap=CreatePixmap(width*6,height,PF_RGBA8888)

		' ***
		
		tex.flags=flags
		'tex.FilterFlags()
				
		tex.no_frames=1'frame_count
		'tex.gltex=tex.gltex[..tex.no_frames]

		' ***
		
		' pixmap -> tex
				
		Local Name
		glGenTextures 1,Varptr Name
		glBindtexture GL_TEXTURE_CUBE_MAP,Name
	
		Local pixmap:TPixmap
	
		For Local i=0 To 5
		
			pixmap=tex.pixmap.Window(width*i,0,width,height)

			' ***
		
			pixmap=AdjustPixmap(pixmap)
			tex.width=pixmap.width
			tex.height=pixmap.height

			Local mipmap
			If tex.flags&8 Then mipmap=True
			Local mip_level=0
			Repeat
				glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format]
				Select i
					Case 0 glTexImage2D GL_TEXTURE_CUBE_MAP_NEGATIVE_X,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
					Case 1 glTexImage2D GL_TEXTURE_CUBE_MAP_POSITIVE_Z,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
					Case 2 glTexImage2D GL_TEXTURE_CUBE_MAP_POSITIVE_X,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
					Case 3 glTexImage2D GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
					Case 4 glTexImage2D GL_TEXTURE_CUBE_MAP_POSITIVE_Y,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
					Case 5 glTexImage2D GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
				End Select
				If Not mipmap Then Exit
				If tex.width=1 And tex.height=1 Exit
				If tex.width>1 tex.width:/2
				If tex.height>1 tex.height:/2

				pixmap=ResizePixmap(pixmap,tex.width,tex.height)
				mip_level:+1
			Forever
			tex.no_mipmaps=mip_level
			
		Next
		
		tex.gltex[0]=Name
		ListAddLast(tex_list,tex)
		
		Return tex
		
	End Function

	Function LoadCubeMapTexture:TTexture(file:Object,flags=1)
	
		Local tex:TTexture=New TTexture
		
		'If FileFind(String(file))=False Then Return Null
		
		tex.file$=String(file)
		tex.file_abs$=FileAbs$(String(file))
		
		' set tex.flags before TexInList
		tex.flags=flags
		tex.FilterFlags()
		
		Local old_tex:TTexture
		old_tex=tex.TexInList()
		If old_tex<>Null Then Return old_tex

		' load pixmap
		tex.pixmap=LoadPixmap(file)

		' convert pixmap to appropriate format
		If tex.pixmap.format<>PF_RGBA8888
			tex.pixmap=tex.pixmap.Convert(PF_RGBA8888)
		EndIf
		
		' ***
		
		' get tex width,height

		Local width=tex.pixmap.width/6
		Local height=tex.pixmap.height

		' ***
		
		'tex.flags=flags
		'tex.FilterFlags()
				
		tex.no_frames=1'frame_count
		'tex.gltex=tex.gltex[..tex.no_frames]
		
		' ***
		
		' pixmap -> tex
			
		Local Name
		glGenTextures 1,Varptr Name
		glBindtexture GL_TEXTURE_CUBE_MAP,Name
	
		Local pixmap:TPixmap
	
		For Local i=0 To 5
		
			pixmap=tex.pixmap.Window(width*i,0,width,height)

			' ***
		
			pixmap=AdjustPixmap(pixmap)
			tex.width=pixmap.width
			tex.height=pixmap.height

			Local mipmap
			If tex.flags&8 Then mipmap=True
			Local mip_level=0
			Repeat
				glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format]
				Select i
					Case 0 glTexImage2D GL_TEXTURE_CUBE_MAP_NEGATIVE_X,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
					Case 1 glTexImage2D GL_TEXTURE_CUBE_MAP_POSITIVE_Z,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
					Case 2 glTexImage2D GL_TEXTURE_CUBE_MAP_POSITIVE_X,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
					Case 3 glTexImage2D GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
					Case 4 glTexImage2D GL_TEXTURE_CUBE_MAP_POSITIVE_Y,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
					Case 5 glTexImage2D GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,mip_level,GL_RGBA8,tex.width,tex.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
				End Select
				If Not mipmap Then Exit
				If tex.width=1 And tex.height=1 Exit
				If tex.width>1 tex.width:/2
				If tex.height>1 tex.height:/2

				pixmap=ResizePixmap(pixmap,tex.width,tex.height)
				mip_level:+1
			Forever
			tex.no_mipmaps=mip_level
			
		Next
		
		tex.gltex[0]=Name
		ListAddLast(tex_list,tex)
	
		Return tex

	End Function

	Method TextureBlend(blend_no)
		
		blend=blend_no
		
	End Method
	
	Method TextureCoords(coords_no)
	
		coords=coords_no
	
	End Method
	
	Method ScaleTexture(u_s#,v_s#)
	
		u_scale#=1.0/u_s#
		v_scale#=1.0/v_s#
	
	End Method
	
	Method PositionTexture(u_p#,v_p#)
	
		u_pos#=-u_p#
		v_pos#=-v_p#
	
	End Method
	
	Method RotateTexture(ang#)
	
		angle#=ang#
	
	End Method
	
	Method TextureWidth()
	
		Return width
	
	End Method
	
	Method TextureHeight()
	
		Return height
	
	End Method
	
	Method TextureName$()
	
		Return file_abs$
	
	End Method
	
	Function GetBrushTexture:TTexture(brush:TBrush,index=0)
	
		Return brush.tex[index]
	
	End Function
	
	Function ClearTextureFilters()
	
		ClearList TTextureFilter.filter_list
	
	End Function
	
	Function TextureFilter(match_text$,flags)
	
		Local filter:TTextureFilter=New TTextureFilter
		filter.text$=match_text$
		filter.flags=flags
		ListAddLast(TTextureFilter.filter_list,filter)
	
	End Function
	
	Method SetCubeFace(face)
		cube_face=face
	End Method
	
	Method SetCubeMode(mode)
		cube_mode=mode
	End Method
	
	' MiniB3D functions
	
	' Essential - offers Blitz3D functionality that cannot be exactly matched

	Method BackBufferToTex(mipmap_no=0,frame=0)
	
		Local x=0,y=0
	
		glBindtexture GL_TEXTURE_2D,gltex[frame]
		glCopyTexImage2D(GL_TEXTURE_2D,mipmap_no,GL_RGBA8,x,TGlobal.height-y-height,width,height,0)

	End Method
	
	
	Method BackBufferToTexExt(mipmap_no=0,frame=0,Kind=GL_RGBA)
		Local x=0,y=0
		glBindtexture GL_TEXTURE_2D,gltex[frame]
		glCopyTexImage2D(GL_TEXTURE_2D,mipmap_no,Kind,x,TGlobal.height-y-height,width,height,0)
		'gluBuild2DMipmaps(GL_TEXTURE_2D, 4,pixmap.width,pixmap.height,Kind, GL_UNSIGNED_BYTE, pixmap.pixels)
	End Method

	
	Method BackBufferToCubeTex(mipmap_no=0)
	
		Local x=0,y=0
	
		glBindtexture GL_TEXTURE_CUBE_MAP_EXT,gltex[0]
		Select cube_face
			Case 0 glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,mipmap_no,GL_RGBA8,x,TGlobal.height-y-height,width,height,0)
			Case 1 glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,mipmap_no,GL_RGBA8,x,TGlobal.height-y-height,width,height,0)
			Case 2 glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X,mipmap_no,GL_RGBA8,x,TGlobal.height-y-height,width,height,0)
			Case 3 glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,mipmap_no,GL_RGBA8,x,TGlobal.height-y-height,width,height,0)
			Case 4 glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,mipmap_no,GL_RGBA8,x,TGlobal.height-y-height,width,height,0)
			Case 5 glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,mipmap_no,GL_RGBA8,x,TGlobal.height-y-height,width,height,0)
		End Select

	End Method
	
	' Extra - offers extra functionality that Blitz3D does not
	
	Method CountMipmaps()
		Return no_mipmaps
	End Method
	
	Method MipmapWidth(mipmap_no)
		If mipmap_no>=0 And mipmap_no<=no_mipmaps
			Return width/(mipmap_no+1)
		Else
			Return 0
		EndIf
	End Method
	
	Method MipmapHeight(mipmap_no)
		If mipmap_no>=0 And mipmap_no<=no_mipmaps
			Return height/(mipmap_no+1)
		Else
			Return 0
		EndIf
	End Method
	
	' Internal - not recommended for general use
	
	Function FileFind:Object(file2:Object)
		Local file:String = String(File2)
		Local fback:String = file
		Local isIncbin:Byte = False
		
		If file[..6] = "incbin" Then IsIncbin = True
		
		If FileType(file)=0
			Repeat
				If isIncbin = True Then 
					file$="incbin::" + Right$(file$,(Len(file$)-Instr(file$,"",1)))
				Else
					file$ = Right$(file$ , (Len(file$) - Instr(file$ , "" , 1) ) )
				EndIf
			Until Instr(file$,"",1)=0
			Repeat
				file$ = Right$(file$ , (Len(file$) - Instr(file$ , "/" , 1) ) )
			Until Instr(file$ , "/" , 1) = 0
			
			If IsIncbin = False Then
				If FileType(file$)=0
					DebugLog "ERROR: Cannot find texture: "+file$
					Return Null
				EndIf
			Else
				If ReadStream(File) = Null Then
					DebugLog "ERROR: Cannot find texture: "+file$
					Return Null
				EndIf	
			EndIf
		EndIf
		
		Return file
		
	End Function
	
	Function FileAbs$(file$)
	
		Local file_abs$
	
		If Instr(file$,":")=False
			file_abs$=CurrentDir$()+"/"+file$
		Else
			file_abs$=file$
		EndIf
		file_abs$=Replace$(file_abs$,"","/")
		
		Return file_abs$
	
	End Function
		
	Method TexInList:TTexture()
	
		' check if tex already exists in list and if so return it

		For Local tex:TTexture=EachIn tex_list
			If file$=tex.file$ And flags=tex.flags
				Return tex
			EndIf
		Next
	
		Return Null
	
	End Method
	
	Method FilterFlags()
	
		' combine specifieds flag with texture filter flags
		For Local filter:TTextureFilter=EachIn TTextureFilter.filter_list
			If Instr(file$,filter.text$) Then flags=flags|filter.flags
		Next
	
	End Method
		
	Function AdjustPixmap:TPixmap(pixmap:TPixmap)
	
		' adjust width and height size to next biggest power of 2 size
		Local width=Pow2Size(pixmap.width)
		Local height=Pow2Size(pixmap.height)

		' check that width and height size are valid (not too big)
		Repeat
			Local t
			glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null
			glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t
			If t Exit
			If width=1 And height=1 RuntimeError "Unable to calculate tex size"
			If width>1 width:/2
			If height>1 height:/2
		Forever

		' if width or height have changed then resize pixmap
		If width<>pixmap.width Or height<>pixmap.height
			pixmap=ResizePixmap(pixmap,width,height)
		EndIf
		
		' return pixmap
		Return pixmap
		
	End Function
	
	Function Pow2Size( n )
		Local t=1
		While t<n
			t:*2
		Wend
		Return t
	End Function
	
	Rem
	Function AdjustPixmap:TPixmap(pixmap:TPixmap)
	
		Local width=Pow2Size(pixmap.width)
		Local height=Pow2Size(pixmap.height)

		If width<>pixmap.width Or height<>pixmap.height
			pixmap=ResizePixmap(pixmap,width,height)
		EndIf
		
		Return pixmap
		
	End Function
	
	Function Pow2Size( n )
		Local t=1
		While t<n
			t:*2
		Wend
		Return t
	End Function
	End Rem
End Type

Type TTextureFilter

	Global filter_list:TList=CreateList()

	Field text$
	Field flags
	
End Type


And in func.bmx change the LoadTexture Function to this:
Function LoadTexture:TTexture(file:Object,flags=1)
	Return TTexture.LoadTexture(file,flags)
End Function


After rebuilding the module you should normally be able to load Textures which are incbin, TImage or TPixmap .

I got an compile error in TTexture at line 243:
TGlobal.Errorhandler.CheckError("TTextrue.bmx",204)

Seems there is no ErrorHandler in TGlobal.

For now I commented line 243 & 244 of TTexture to check if everything else works.
And it does!!!

Now this is what I call a nice solution.
1. I can now create a cube (or any other shape) with individual surfaces and textures. Yes!
2. I can combine this 3D object with my 2D interface. Great effect!
3. I can reuse my 2D images as texures for the 3D objects!
I'm in heaven ;-)

Thanks a lot for all the effort and support.