Lighting a multi-mesh textured cube.

Blitz3D Forums/Blitz3D Beginners Area/Lighting a multi-mesh textured cube.

R Ellingworth(Posted 2010) [#1]
First problem - I wanted to create a textured cube and my first try was to use CreateCube, then load a texture and apply it to the cube.

It works, but the same texture is applied to each face of the cube. What I wanted was a different texture on each face.

After a bit of thought I wrote this function:



This creates a cube consisting of a total of 7 meshes - one parent mesh with nothing in it and 6 child meshes for each of the 6 cube faces. You can then extract each face mesh and apply a different texture to it. Great.

Problem comes when I try to apply lighting to it. It just doesn't seem to work. I turn off all ambient light and then create a light which I point at the cube. I just get total blackness. However, if I replace my multi-mesh cube with one created using CreateCube and the same texture on each face then lighting works just fine.

Have I misunderstood how lighting works with multi-mesh entities?


dawlane(Posted 2010) [#2]
Could be that the problem relates to which way the surface normal is facing. Though I my self would just use a 3D modelling tool with a UV Editor as it saves a lot of work.


R Ellingworth(Posted 2010) [#3]
Thanks for that. It put me on the right track.

What I had to do in the end is call UpdateNormals for every mesh in the cube. I had thought that just calling UpdateNormals for the parent mesh would update all the children as well (recursively) but it clearly doesn't.

Once I did that the lighting all works fine.

I assume it is necessary to create a new sub-mesh for every part that is to have a different texture. I had wondered if it was possible to just create surfaces instead, but I don't seem to be able to apply a texture to a surface, only to a mesh.


dawlane(Posted 2010) [#4]
Have you tried to use a brush and then createsurface/paintsurface?


Leon Drake(Posted 2010) [#5]
this code has been floating around forever and it does basically the same thing.

Function LoadSkyBox( file$ )
	m=CreateMesh()
	;front face
	DebugLog "Loading "+file$+"_FR.jpg"
	b=LoadBrush( file$+"_FR.jpg",1 )
	s=CreateSurface( m,b )
	AddVertex s,-1,+1,-1,0,0:AddVertex s,+1,+1,-1,1,0
	AddVertex s,+1,-1,-1,1,1:AddVertex s,-1,-1,-1,0,1
	AddTriangle s,0,1,2:AddTriangle s,0,2,3:
	FreeBrush b
	;right face
	b=LoadBrush( file$+"_LF.jpg",1 )
	s=CreateSurface( m,b )
	AddVertex s,+1,+1,-1,0,0:AddVertex s,+1,+1,+1,1,0
	AddVertex s,+1,-1,+1,1,1:AddVertex s,+1,-1,-1,0,1
	AddTriangle s,0,1,2:AddTriangle s,0,2,3
	FreeBrush b
	;back face
	b=LoadBrush( file$+"_BK.jpg",1 )
	s=CreateSurface( m,b )
	AddVertex s,+1,+1,+1,0,0:AddVertex s,-1,+1,+1,1,0
	AddVertex s,-1,-1,+1,1,1:AddVertex s,+1,-1,+1,0,1
	AddTriangle s,0,1,2:AddTriangle s,0,2,3
	FreeBrush b
	;left face
	b=LoadBrush( file$+"_RT.jpg",1 )
	s=CreateSurface( m,b )
	AddVertex s,-1,+1,+1,0,0:AddVertex s,-1,+1,-1,1,0
	AddVertex s,-1,-1,-1,1,1:AddVertex s,-1,-1,+1,0,1
	AddTriangle s,0,1,2:AddTriangle s,0,2,3
	FreeBrush b
	;top face
	b=LoadBrush( file$+"_UP.jpg",1 )
	s=CreateSurface( m,b )
	AddVertex s,-1,+1,+1,0,1:AddVertex s,+1,+1,+1,0,0
	AddVertex s,+1,+1,-1,1,0:AddVertex s,-1,+1,-1,1,1
	AddTriangle s,0,1,2:AddTriangle s,0,2,3
	FreeBrush b
	;bottom face	
	b=LoadBrush( file$+"_DN.jpg",1 )
	s=CreateSurface( m,b )
	AddVertex s,-1,-1,-1,1,0:AddVertex s,+1,-1,-1,1,1
	AddVertex s,+1,-1,+1,0,1:AddVertex s,-1,-1,+1,0,0
	AddTriangle s,0,1,2:AddTriangle s,0,2,3
	FreeBrush b
	ScaleMesh m,100,100,100
	FlipMesh m
	EntityFX m,1
	Return m
End Function



Kryzon(Posted 2010) [#6]
For those that didn't get it, he missed the UpdateNormals() function, since he only supplied XYZ and UV data to the vertices, and not their normals too (and you don't really need to. That function calculates them for you).

Vertices' normals are essential for correct lighting. It's part of the fixed-function lighting equation (and most programmed approaches as well).
That skybox function doesn't use UpdateNormals because skyboxes don't need lighting - they're set to fullbright anyway.

I assume it is necessary to create a new sub-mesh for every part that is to have a different texture. I had wondered if it was possible to just create surfaces instead, but I don't seem to be able to apply a texture to a surface, only to a mesh.


One Mesh can have several Surfaces, each one with a different Brush applied. See more info here. With PaintSurface you can apply a certain brush to a specific surface - just be careful not to overdo it: each new (populated) surface costs a little bit of performance.


K(Posted 2010) [#7]
PaintSurface(GetSurface(Mesh,index%),Brush) works quite well. I do that number a lot