Ok, here it is! I'd be really happy if some people help to solve the mentioned issues.
; WIP: Lightmapper with GI. By Dieter Marfurt. PickedUVW Functions provided by Mikkel Fredborg.
; The whole thing (at least my part) is rather a quick hack, not yet a useful program. 3 Things
; have to be done next:
; - Get rid of the lightmap artefacts with masked textures (see red object) - this is where I need help.
; - Optimize Speed by about 10'000 percent :)
; - Add smart UV Packing (DDS is no excuse for not to do so)
; Other than that - have fun!
; Please note in the planar mapping function GOTO is used twice... this is a good exampe for
; a sophisticated, intelligent use of GOTO :o)
; Description of Functionality
; ----------------------------
; First the Mesh is unwelded, so all Triangles have their own 3 Vertices.
; Then a second UV Coordinates set is created, using Planar mapping, so every triangle has it's
; space on the lightmap Texture, relative to it's size in the world.
; THen each triangle is scanned with a given stepwidth. A pivot and a camera is used to
; check the visibility of the lights from every possible location on the surface of the tirangle. A linepick
; is then done for every scanned cell and Fredbords PickedU/V functions will tell us where to paint the texel
; on the texture.
Graphics3D 800,600,32,2
Global workbuffer
workbuffer=BackBuffer()
SetBuffer workbuffer
; some important variables
; *************************
; lightmapers scanner stepwidth. 1.0 would be equal the texture resolution, at least in theory
; (the higher the faster, eg. for draft mode, the lower, the more accurate)
Global sstep#=2.0
Global csp_ambient=$111111 ; ambient light
Global nlites=1 ; number of randomly created lights (see below) ((zero to number!))
Global tex_maxsize#=512 ; lightmap texture size
Global margin=4 ; lightmappers margin in pixel, helps to prevent bleeding edges
; set global illumination influence
Global col_shift#=2.1;2.3 ; be carefull with this "afterburner" (lower=more GI)
Global gi_r=150 ; dominance: 0 to 255
Global gi_g=150
Global gi_b=150
; offset of the lightmappers visibility pivots to the surface
Global piv_offset#=0.001
; some variables used by fredborgs pickedUVW functions
Type PickedTri
Field ent,surf,tri ;picked entity, surface and triangle
Field px#,py#,pz# ;picked xyz
Field pu#[1], pv#[1] ,pw#[1] ;picked uvw x 2
Field vx#[2], vy#[2] ,vz#[2] ;vertex xyz
Field vnx#[2], vny#[2] ,vnz#[2] ;vertex normals
Field vu#[5], vv#[5] ,vw#[5] ;vertex uvw x 2
End Type
Global ptri.pickedtri = New pickedtri
; end of some variables used by fredborgs pickedUVW functions
Const ssstep#=0.0001 ;dummy stepwidth to allow varibale FOR stepwidths
Global camera
camera=CreateCamera()
CameraRange camera,0.001,100
c_transz#=-10
c_transh#=4
TranslateEntity camera,0,c_transz#,c_transh#
CameraProjMode camera,0
Global minrel#=0
; create some random "lights" fr the test scene
Dim lites_pivot(nlites)
Dim lites_r#(nlites)
Dim lites_g#(nlites)
Dim lites_b#(nlites)
Dim lites_x#(nlites)
Dim lites_y#(nlites)
Dim lites_z#(nlites)
Dim lites_pitch#(nlites)
Dim lites_yaw#(nlites)
Dim lites_roll#(nlites)
Dim lites_range#(nlites)
For i=0 To nlites
lites_pivot(i)=CreatePivot()
dummy=CreateCube(lites_pivot(i)) ; this will be used for alpha and maskmode checks
ScaleEntity dummy,.1,.1,.1
lites_r(i)=155
lites_g(i)=155
lites_b(i)=155
; lites_r(i)=Rand(0,1)*255
; lites_g(i)=Rand(255)
; lites_b(i)=Rand(0,1)*255
EntityColor dummy,lites_r(i),lites_g(i),lites_b(i)
PositionEntity lites_pivot(i),Rnd(-10,10),Rnd(2,5),Rnd(-10,10)
EntityPickMode lites_pivot(i),2
lites_range#(i)=15;+Rnd(30)
EntityFX dummy,1
Next
Global pivot=CreatePivot()
Global GI_cam, UV_cam
GI_cam=CreateCamera()
UV_cam=CreateCamera()
CameraProjMode GI_cam,0
CameraProjMode UV_cam,0
Global alpha_cam=CreateCamera()
CameraProjMode alpha_cam,0
CameraViewport alpha_cam,0,0,1,1
CameraZoom alpha_cam,100.0
CameraRange alpha_cam,0.0001,100
RotateEntity gi_cam,-90,0,0
CameraZoom gi_cam,0.85
EntityParent gi_cam,pivot
Global gi_res=16
CameraViewport gi_cam,0,0,gi_res,gi_res
CameraFogMode gi_cam,0
CameraFogRange gi_cam,0,100.0
Global mesh
mesh=csp_MyCreateDummyMap()
Global max_tris
Global x_min#,x_max#,y_min#,y_max#,z_min#,z_max#
Dim tris_arr_u#(0,0,0)
Dim tris_arr_v#(0,0,0)
Dim tris_arr_dir(0,0)
Dim tris_arr_centerxyz#(0,0,2)
Dim tris_arr_normals#(0,0,2)
Global lima_img
lima_img=CreateImage(tex_maxsize,tex_maxsize)
mesh=csp_unweld(mesh)
EntityPickMode mesh,2
EntityFX mesh,16 ;Or 1
csp_planarmap(mesh)
; lightmap the map....
;*********************
EntityColor mesh, gi_r,gi_g,gi_b ; set global illumination level
EntityFX mesh,1 Or 16
csp_lightmap(mesh)
EntityFX mesh,0
lima=CreateTexture(tex_maxsize,tex_maxsize,48)
CopyRect 0,0,tex_maxsize,tex_maxsize,0,0,ImageBuffer(lima_img),TextureBuffer(lima)
EntityTexture mesh,lima,0,1
TextureCoords lima,1
TextureBlend lima, 2;5
FreeImage lima_img
EntityColor mesh,255,255,255
EntityFX mesh,17
SetBuffer BackBuffer()
For i=0 To nlites
ShowEntity lites_pivot(i)
Next
FreeEntity gi_cam
FreeEntity uv_cam
FreeEntity alpha_cam
CameraProjMode camera,1
; ------------- main --------------------------------------------------------------------------------
While KeyDown(1)=0
PositionEntity camera,Sin(c_a#)*c_transz,c_transh,Cos(c_a#)*c_transz
PointEntity camera,mesh
c_a#=(c_a#+1) Mod 360.0
RenderWorld()
Flip
Wend
End
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; this will apply planar-mapping to the 2nd UV channel of the mesh. THe biggest triangle will be used to
; determine the max scaling factor world vs texture. THe function will then try to pack the triangles to the
; lightmap. If there isn't enough space it ill automaticly reduce the scaling factor and try again until
; all triangles fit in tex_maxsize*tex_maxsize.
; The packing is completely unoptimized (other than rotating the tris to a more horizontal shape). Since
; this function is pretty much independent from the lightmapper, the PACKING of the planar may be optimized
; without troubles with the rest of the code.
Function csp_planarmap(mesh)
CameraProjMode uv_cam,1
;uv_pivot=CreatePivot()
rel#=csp_lima_minrel#(mesh,tex_maxsize)
minrel=rel
csp_GetMaxTris(mesh)
surfs=CountSurfaces(mesh)
Dim tris_arr_u#(surfs,max_tris,2)
Dim tris_arr_v#(surfs,max_tris,2)
Dim tris_arr_centerxyz#(surfs,max_tris,2)
Dim tris_arr_normals#(surfs,max_tris,2)
Dim tris_arr_dir(surfs,max_tris)
For s=1 To surfs
surf=GetSurface(mesh,s)
tris=CountTriangles(surf)
;Print max_tris
;Print tris
;Print "--------"
For t=0 To tris-1
; dtermine primary axis
x0#=VertexX(surf,TriangleVertex(surf,t,0))
y0#=VertexY(surf,TriangleVertex(surf,t,0))
z0#=VertexZ(surf,TriangleVertex(surf,t,0))
TFormPoint x0,y0,z0,mesh,0 : x0=TFormedX() : y0=TFormedY() : z0=TFormedZ()
x1#=VertexX(surf,TriangleVertex(surf,t,1))
y1#=VertexY(surf,TriangleVertex(surf,t,1))
z1#=VertexZ(surf,TriangleVertex(surf,t,1))
TFormPoint x1,y1,z1,mesh,0 : x1=TFormedX() : y1=TFormedY() : z1=TFormedZ()
x2#=VertexX(surf,TriangleVertex(surf,t,2))
y2#=VertexY(surf,TriangleVertex(surf,t,2))
z2#=VertexZ(surf,TriangleVertex(surf,t,2))
TFormPoint x2,y2,z2,mesh,0 : x2=TFormedX() : y2=TFormedY() : z2=TFormedZ()
; we're doing some darn good projectional mapping here! (better than what some tutorials suggest)
; so our Tris will not be distorted on the texture.
x4#=(x0+x1+x2)/3.0 ; tri center
y4#=(y0+y1+y2)/3.0
z4#=(z0+z1+z2)/3.0
px#=x1-x0 ; determine tri normal
py#=y1-y0
pz#=z1-z0
qx#=x2-x0
qy#=y2-y0
qz#=z2-z0
nx#=(py*qz)-(pz*qy)
ny#=(pz*qx)-(px*qz)
nz#=(px*qy)-(py*qx)
tris_arr_centerxyz#(s,t,0)=x4 ; uhm, probably not in use... however
tris_arr_centerxyz#(s,t,1)=y4
tris_arr_centerxyz#(s,t,2)=z4
tris_arr_normals#(s,t,0)=nx
tris_arr_normals#(s,t,1)=ny
tris_arr_normals#(s,t,2)=nz
PositionEntity uv_cam,x4,y4,z4
AlignToVector uv_cam,nx,ny,nz,0
RotateEntity uv_cam,EntityPitch(uv_cam),EntityYaw(uv_cam),0
MoveEntity uv_cam,0,0,-rel#/4.0 ; make sure to sync this values with the same steps in csp_lightmap(). Probably better use a variable for 4.0...
CameraProject uv_cam, x0,y0,z0
u0#=ProjectedX()
v0#=ProjectedY()
CameraProject uv_cam, x1,y1,z1
u1#=ProjectedX()
v1#=ProjectedY()
CameraProject uv_cam, x2,y2,z2
u2#=ProjectedX()
v2#=ProjectedY()
xdis#=max(Abs(x0-x1),Abs(x0-x2))
ydis#=max(Abs(y0-y1),Abs(y0-y2))
zdis#=max(Abs(z0-z1),Abs(z0-z2))
x_min=min(x_min,min3(x0,x1,x2))
y_min=min(y_min,min3(y0,y1,y2))
z_min=min(z_min,min3(z0,z1,z2))
x_max=max(x_max,max3(x0,x1,x2))
y_max=max(y_max,max3(y0,y1,y2))
z_max=max(z_max,max3(z0,z1,z2))
;------------
u_min=min(u_min,min3(u0,u1,u2))
v_min=min(v_min,min3(v0,v1,v2))
u_max=max(u_max,max3(u0,u1,u2))
v_max=max(v_max,max3(v0,v1,v2))
;store each tris uvs relative to zero
tris_arr_u(s,t,0)=u0 -min3(u0,u1,u2)
tris_arr_u(s,t,1)=u1 -min3(u0,u1,u2)
tris_arr_u(s,t,2)=u2 -min3(u0,u1,u2)
tris_arr_v(s,t,0)=v0 -min3(v0,v1,v2)
tris_arr_v(s,t,1)=v1 -min3(v0,v1,v2)
tris_arr_v(s,t,2)=v2 -min3(v0,v1,v2)
Color 255,0,0
triLine tris_arr_u(s,t,0),tris_arr_v(s,t,0),tris_arr_u(s,t,1),tris_arr_v(s,t,1),tris_arr_u(s,t,2),tris_arr_v(s,t,2)
Next
Next
Color 255,255,255
Flip ; just some screen output for the user
; UV PACKER : feel free to optimize this A LOT!!
;pack tris on lm...
largest_tri#=max(u_max-u_min,v_max-v_min)
;multiplyer To make sure even the largest tris fits on texture
mply#=tex_maxsize#/largest_tri#
.tryagain2 ; restart here if not all tris fit on texture (may use boolen search, instead of reducing scaling, tho this doesn´t seem to be the speed bottleneck here)
Cls
xoff#=margin
yoff#=margin
max_height#=0
For s=1 To surfs
;surfs
surf=GetSurface(mesh,s)
tris=CountTriangles(surf)
For t=0 To tris-1
; arrang tris horizontal
height#=Abs( max3(tris_arr_v(s,t,0),tris_arr_v(s,t,1),tris_arr_v(s,t,2))-min3(tris_arr_v(s,t,0),tris_arr_v(s,t,1),tris_arr_v(s,t,2)) ) ; tri höhe?
csp_RotateUVs90Plus(s,t)
height2#=Abs( max3(tris_arr_v(s,t,0),tris_arr_v(s,t,1),tris_arr_v(s,t,2))-min3(tris_arr_v(s,t,0),tris_arr_v(s,t,1),tris_arr_v(s,t,2)) ) ; tri höhe nach einer 90 grad drehung
If height2>height Then
csp_RotateUVs90Plus(s,t)
EndIf
height#=Abs( max3(tris_arr_v(s,t,0),tris_arr_v(s,t,1),tris_arr_v(s,t,2))-min3(tris_arr_v(s,t,0),tris_arr_v(s,t,1),tris_arr_v(s,t,2)) )
If height>max_height Then max_height=height ; remeber max tris height on this line for next line break
width#=Abs( max3(tris_arr_u(s,t,0),tris_arr_u(s,t,1),tris_arr_u(s,t,2))-min3(tris_arr_u(s,t,0),tris_arr_u(s,t,1),tris_arr_u(s,t,2)) )
.tryagain ; jump here after a "line break"
; check if tris still fits on current "line"...
x0#=(xoff+tris_arr_u(s,t,0)*mply)
x1#=(xoff+tris_arr_u(s,t,1)*mply)
x2#=(xoff+tris_arr_u(s,t,2)*mply)
y0#=(yoff+tris_arr_v(s,t,0)*mply)
y1#=(yoff+tris_arr_v(s,t,1)*mply)
y2#=(yoff+tris_arr_v(s,t,2)*mply)
If max3(x0,x1,x2)>tex_maxsize#-margin ; force linebreak!
xoff=margin
yoff=margin+yoff+max_height*mply
max_height=0
If KeyDown(1)=1 Then End
Goto tryagain
EndIf
If max3(y0,y1,y2)>tex_maxsize#-margin ; tris won't fit all on texture!
s=1
mply=mply*0.99 ; reduce main xyz versus uv scaling factor
max_height=0
If KeyDown(1)=1 Then End ; panic button
Goto tryagain2
EndIf
; visually seek UVs
TriLine(x0,y0,x1,y1,x2,y2)
; and set UVs!
VertexTexCoords surf,TriangleVertex(surf,t,0),x0/tex_maxsize,y0/tex_maxsize ,0,1
VertexTexCoords surf,TriangleVertex(surf,t,1),x1/tex_maxsize,y1/tex_maxsize ,0,1
VertexTexCoords surf,TriangleVertex(surf,t,2),x2/tex_maxsize,y2/tex_maxsize ,0,1
xoff=margin+xoff+width*mply
Next
Next
Rect 0,0,tex_maxsize,tex_maxsize,0
CameraProjMode uv_cam,0
csp_ShowBackbuffer()
Color 0,255,0
Locate 0,GraphicsHeight()-20
Print "Pretty bad UV packing so far... Press a key to continue"
Color 255,255,255
WaitKey()
End Function
Function csp_ShowBackbuffer()
CopyRect 0,0,GraphicsWidth(),GraphicsHeight(),0,0,BackBuffer(),FrontBuffer()
End Function
Function csp_lightmap(mesh)
help=csp_CreateHelperQuad() ; used for "near-surface picking"
Cls
surfs=CountSurfaces(mesh)
For s=1 To surfs
surf=GetSurface(mesh,s)
tris=CountTriangles(surf)
For t=0 To tris-1
x0#=VertexX(surf,TriangleVertex(surf,t,0))
y0#=VertexY(surf,TriangleVertex(surf,t,0))
z0#=VertexZ(surf,TriangleVertex(surf,t,0))
TFormPoint x0,y0,z0,mesh,0
x0=TFormedX():y0=TFormedY():z0=TFormedZ()
x1#=VertexX(surf,TriangleVertex(surf,t,1))
y1#=VertexY(surf,TriangleVertex(surf,t,1))
z1#=VertexZ(surf,TriangleVertex(surf,t,1))
TFormPoint x1,y1,z1,mesh,0
x1=TFormedX():y1=TFormedY():z1=TFormedZ()
x2#=VertexX(surf,TriangleVertex(surf,t,2))
y2#=VertexY(surf,TriangleVertex(surf,t,2))
z2#=VertexZ(surf,TriangleVertex(surf,t,2))
TFormPoint x2,y2,z2,mesh,0
x2=TFormedX():y2=TFormedY():z2=TFormedZ()
x4#=(x0+x1+x2)/3.0 ; tri center
y4#=(y0+y1+y2)/3.0
z4#=(z0+z1+z2)/3.0
px#=x1-x0 ; determine tri normal
py#=y1-y0
pz#=z1-z0
qx#=x2-x0
qy#=y2-y0
qz#=z2-z0
nx#=(py*qz)-(pz*qy)
ny#=(pz*qx)-(px*qz)
nz#=(px*qy)-(py*qx)
PositionEntity uv_cam,x4,y4,z4
AlignToVector uv_cam,nx,ny,nz,0
RotateEntity uv_cam,EntityPitch(uv_cam),EntityYaw(uv_cam),0
TurnEntity uv_cam,180,0,0
PositionEntity help,x4,y4,z4
AlignToVector help,nx,ny,nz,0
; TurnEntity uv_cam,0,0,0 ; wt..?
MoveEntity help,0,0,.001
MoveEntity uv_cam,0,0,-minrel/4.0
CameraRange uv_cam,(minrel/4.0)-.0001,(minrel/4.0)+.0001
CameraProjMode uv_cam,1
CameraProject uv_cam, x0,y0,z0
u0#=ProjectedX()
v0#=ProjectedY()
CameraProject uv_cam, x1,y1,z1
u1#=ProjectedX()
v1#=ProjectedY()
CameraProject uv_cam, x2,y2,z2
u2#=ProjectedX()
v2#=ProjectedY()
CameraProjMode uv_cam,0
up_min#=min3#(u0,u1,u2)
vp_min#=min3#(v0,v1,v2)
up_max#=max3#(u0,u1,u2)
vp_max#=max3#(v0,v1,v2)
pick_rad#=0.01;001
texox#=0; pixel offset on texture to draw
texoy#=0
po#=0.01
AppTitle "surf:"+s+" tri:"+t+" of "+surfs+"/"+tris +" ,v/u: "+v#+" / "+u#
For v#=vp_min#-1.0 To vp_max#+1.0 Step ssstep# ; v
For u#=up_min#-1.0 To up_max#+1.0 Step ssstep# ; u
;pick helper quad
EntityPickMode mesh,0
EntityPickMode help,2
p=CameraPick(uv_cam,u,v)
EntityPickMode mesh,2
EntityPickMode help,0
If p=help Then
; pick map tri
; remember projection location
re_x#=EntityX(uv_cam,1)
re_y#=EntityY(uv_cam,1)
re_z#=EntityZ(uv_cam,1)
; repos camera on near-surface picked loaction
PositionEntity uv_cam,PickedX(),PickedY(),PickedZ()
p=CameraPick(uv_cam,GraphicsWidth()/2.0,GraphicsHeight()/2.0) ; pick map surface
PositionEntity uv_cam,re_x,re_y,re_z,1 ; restore camera
EndIf
If KeyDown(1) Then End ; don´t panic :)
If p=mesh Then ; picked main mesh?
ptris=PickedTriangle()
If ptris=t ; picked a to-be-scanned triangle?
HideEntity help
CameraProjMode uv_cam,0
CameraProjMode gi_cam,1
csp_lima_scancell() ; determine light factor on the surface location
CameraProjMode uv_cam,1
CameraProjMode gi_cam,0
ShowEntity help
EndIf
EndIf
u=u+(sstep-ssstep) ; force variable FOR stepwidth
Next
v=v+(sstep-ssstep) ; force variable FOR stepwidth
Next
Next
Next
End Function
; gets the light factor at a previously pickes location o n a surface
Function csp_lima_scancell()
PositionEntity pivot, PickedX(),PickedY(),PickedZ()
AlignToVector(pivot,PickedNX(),PickedNY(),PickedNZ(),2)
MoveEntity pivot,0,0,piv_offset#
rgb1=csp_grab_gi() ; get global illumination factor
PositionEntity alpha_cam, PickedX(),PickedY(),PickedZ()
PositionEntity pivot, PickedX(),PickedY(),PickedZ()
AlignToVector(pivot,PickedNX(),PickedNY(),PickedNZ(),0)
MoveEntity pivot,0,0,piv_offset#
For i=0 To nlites
If EntityVisible(lites_pivot(i),pivot) ; can see light directly = no alpha or masks or opaque obstructors
; calc light intensity from the distance
r0=(((lites_range#(i)-(EntityDistance(pivot,lites_pivot(i))))*5.0)/256.0)*lites_r(i)
g0=(((lites_range#(i)-(EntityDistance(pivot,lites_pivot(i))))*5.0)/256.0)*lites_g(i)
b0=(((lites_range#(i)-(EntityDistance(pivot,lites_pivot(i))))*5.0)/256.0)*lites_b(i)
If r0>255 Then r0=255
If r0<0 Then r0=0
If g0>255 Then g0=255
If g0<0 Then g0=0
If b0>255 Then b0=255
If b0<0 Then b0=0
rr0=rr0+r0
gg0=gg0+g0
bb0=bb0+b0
Else ; may be obstructed, or alpha or mask..
EntityColor mesh,0,0,0 ; (everything that is obstructing 100% will be totally black)
EntityFX mesh,17
PointEntity alpha_cam,lites_pivot(i)
CameraProjMode alpha_cam,1
CameraProjMode gi_cam,0
;SetBuffer BackBuffer()
RenderWorld()
argb=ReadPixel(0,0) And $ffffff
argb2=0
If argb <>0 ; is the rendered pixel not black? then it must be an alpha (or mask) texel!
EntityColor mesh,127,127,127
RenderWorld()
argb2=ReadPixel(0,0) And $ffffff
EndIf
CameraProjMode alpha_cam,0 ; restore colors etc.
CameraProjMode gi_cam,1
EntityColor mesh,gi_r,gi_g,gi_b
;determine light factor based on distance to light source relative to the rendered pixel color
r0=(((lites_range#(i)-(EntityDistance(pivot,lites_pivot(i))))*5.0)/256.0)*((argb2 Shr 16) And $FF)
g0=(((lites_range#(i)-(EntityDistance(pivot,lites_pivot(i))))*5.0)/256.0)*((argb2 Shr 8) And $FF)
b0=(((lites_range#(i)-(EntityDistance(pivot,lites_pivot(i))))*5.0)/256.0)*((argb2) And $FF)
If r0>255 Then r0=255
If r0<0 Then r0=0
If g0>255 Then g0=255
If g0<0 Then g0=0
If b0>255 Then b0=255
If b0<0 Then b0=0
rr0=rr0+r0
gg0=gg0+g0
bb0=bb0+b0
EndIf
Next
r0=rr0;/(nlites+1)
g0=gg0;/(nlites+1)
b0=bb0;/(nlites+1)
If r0>255 Then r0=255
If r0<0 Then r0=0
If g0>255 Then g0=255
If g0<0 Then g0=0
If b0>255 Then b0=255
If b0<0 Then b0=0
rgb0=(r0 Shl 16) Or (g0 Shl 8) Or (b0)
; mix ambient, global illumintaion light and point lights
rgb=csp_toneRGB(rgb1,rgb0) ; point lights + gi
rgb=csp_addRGB(rgb,csp_ambient) ; +ambient
; finally lot the lightmap texel (to an image for now, for speed reasons)
Color 0,0,rgb
SetBuffer ImageBuffer(lima_img)
; Plot pickedu(1)*(tex_maxsize#),pickedv(1)*(tex_maxsize#) ; single pixel is more accurate, but requires a higher scan resolution (takes much more time)
Rect pickedu(1)*(tex_maxsize#)-1,pickedv(1)*(tex_maxsize#)-1,3,3,1 ; is quicker, but also not so accurate
SetBuffer workbuffer
End Function
; calculates Global Illumination from a render (camera etc. must be set uo correctly)
Function csp_grab_gi()
RenderWorld()
LockBuffer workbuffer
r_#=0
g_#=0
b_#=0
For j=0 To gi_res-1
For i=0 To gi_res-1
rgb=ReadPixelFast(i,j) And $ffffff
r=(rgb And $ff0000) Shr 16
g=(rgb And $ff00) Shr 8
b=(rgb And $ff)
r_=r_+r
g_=g_+g
b_=b_+b
Next
Next
UnlockBuffer workbuffer
r_= r_/(Float(gi_res)^col_shift#)
g_= g_/(Float(gi_res)^col_shift#)
b_= b_/(Float(gi_res)^col_shift#)
If r_>255 Then r_=255
If g_>255 Then g_=255
If b_>255 Then b_=255
Return (r_ Shl 16) Or (g_ Shl 8) Or (b_)
End Function
Function csp_addRGB(rgb1,rgb2)
r=(rgb1 Shr 16) + (rgb2 Shr 16)
g=((rgb1 And $ff00) Shr 8) + ((rgb2 And $ff00) Shr 8)
b=((rgb1 And $ff)) + ((rgb2 And $ff))
If r>255 Then r=255
If g>255 Then g=255
If b>255 Then b=255
rgb=(r Shl 16) Or (g Shl 8) Or (b)
Return rgb
End Function
; teints a given color with the hue of an other color
Function csp_toneRGB(rgb1,rgb2)
r1=(rgb1 Shr 16)
g1=((rgb1 And $ff00) Shr 8)
b1=((rgb1 And $ff))
r2=(rgb2 Shr 16)
g2=((rgb2 And $ff00) Shr 8)
b2=((rgb2 And $ff))
rgbmin=min3(r1,g1,b1)
rgbmax=max3(r1,g1,b1)
rgbdis=(rgbmax-rgbmin)/1.5;/2 ; /2.0 would be the same brightness, 1.5 makes it a little darker
rp=(r1-(rgbmin+rgbdis))
gp=(g1-(rgbmin+rgbdis))
bp=(b1-(rgbmin+rgbdis))
r=r2+rp
g=g2+gp
b=b2+bp
If r>255 Then r=255
If g>255 Then g=255
If b>255 Then b=255
If r<0 Then r=0
If g<0 Then g=0
If b<0 Then b=0
rgb=(r Shl 16) Or (g Shl 8) Or (b)
Return rgb
End Function
Function TriLine(x0,y0,x1,y1,x2,y2)
Line x0,y0,x1,y1
Line x1,y1,x2,y2
Line x2,y2,x0,y0
End Function
; flips UVs (rather than rotating..)
Function csp_RotateUVs90Plus(s,t)
rem_u#=tris_arr_u(s,t,0)
tris_arr_u(s,t,0)=tris_arr_v(s,t,0)
tris_arr_v(s,t,0)=rem_u#
rem_u#=tris_arr_u(s,t,1)
tris_arr_u(s,t,1)=tris_arr_v(s,t,1)
tris_arr_v(s,t,1)=rem_u#
rem_u#=tris_arr_u(s,t,2)
tris_arr_u(s,t,2)=tris_arr_v(s,t,2)
tris_arr_v(s,t,2)=rem_u#
End Function
Function csp_RotateUVsPlus(s,t)
rem_u#=tris_arr_u(s,t,0)
rem_v#=tris_arr_v(s,t,0)
tris_arr_u(s,t,0)=tris_arr_u(s,t,1)
tris_arr_v(s,t,0)=tris_arr_v(s,t,1)
tris_arr_u(s,t,1)=tris_arr_u(s,t,2)
tris_arr_v(s,t,1)=tris_arr_v(s,t,2)
tris_arr_u(s,t,2)=rem_u
tris_arr_v(s,t,2)=rem_v
End Function
Function min3#(a#,b#,c#)
If (a<=b) And (a<=c) Then Return a
If (b<=a) And (b<=c) Then Return b
Return c
End Function
Function max3#(a#,b#,c#)
If (a>=b) And (a>=c) Then Return a
If (b>=a) And (b>=c) Then Return b
Return c
End Function
Function min#(a#,b#)
If a<b Then Return a
Return b
End Function
Function max#(a#,b#)
If a>b Then Return a
Return b
End Function
; saves the max triscount of any surface in the mesh in the global variable max_tris (waste od DIM ram, I know)
Function csp_GetMaxTris(mesh)
max_tris=0
surfs=CountSurfaces(mesh)
For s=1 To surfs
surf=GetSurface(mesh,s)
tris=CountTriangles(surf)
If tris >max_tris Then max_tris=tris
Next
; Return max_tris
End Function
Function csp_unweld(mesh)
mesh2=CreateMesh()
surfs=CountSurfaces(mesh)
For s=1 To surfs
surf=GetSurface(mesh,s)
brush2=GetSurfaceBrush(surf)
surf2=CreateSurface(mesh2)
PaintSurface surf2,brush2
;surf2=GetSurface(mesh2,s)
;ClearSurface surf2,1,1
tris=CountTriangles(surf)
For t=0 To tris-1
x0#=VertexX(surf,TriangleVertex(surf,t,0))
y0#=VertexY(surf,TriangleVertex(surf,t,0))
z0#=VertexZ(surf,TriangleVertex(surf,t,0))
u0a#=VertexU(surf,TriangleVertex(surf,t,0),0)
v0a#=VertexV(surf,TriangleVertex(surf,t,0),0)
u0b#=VertexU(surf,TriangleVertex(surf,t,0),1)
v0b#=VertexV(surf,TriangleVertex(surf,t,0),1)
nx0#=VertexNX(surf,TriangleVertex(surf,t,0))
ny0#=VertexNY(surf,TriangleVertex(surf,t,0))
nz0#=VertexNZ(surf,TriangleVertex(surf,t,0))
v0_r#=VertexRed(surf,TriangleVertex(surf,t,0))
v0_g#=VertexGreen(surf,TriangleVertex(surf,t,0))
v0_b#=VertexBlue(surf,TriangleVertex(surf,t,0))
v0_a#=VertexAlpha(surf,TriangleVertex(surf,t,0))
x1#=VertexX(surf,TriangleVertex(surf,t,1))
y1#=VertexY(surf,TriangleVertex(surf,t,1))
z1#=VertexZ(surf,TriangleVertex(surf,t,1))
u1a#=VertexU(surf,TriangleVertex(surf,t,1),0)
v1a#=VertexV(surf,TriangleVertex(surf,t,1),0)
u1b#=VertexU(surf,TriangleVertex(surf,t,1),1)
v1b#=VertexV(surf,TriangleVertex(surf,t,1),1)
nx1#=VertexNX(surf,TriangleVertex(surf,t,1))
ny1#=VertexNY(surf,TriangleVertex(surf,t,1))
nz1#=VertexNZ(surf,TriangleVertex(surf,t,1))
v1_r#=VertexRed(surf,TriangleVertex(surf,t,1))
v1_g#=VertexGreen(surf,TriangleVertex(surf,t,1))
v1_b#=VertexBlue(surf,TriangleVertex(surf,t,1))
v1_a#=VertexAlpha(surf,TriangleVertex(surf,t,1))
x2#=VertexX(surf,TriangleVertex(surf,t,2))
y2#=VertexY(surf,TriangleVertex(surf,t,2))
z2#=VertexZ(surf,TriangleVertex(surf,t,2))
u2a#=VertexU(surf,TriangleVertex(surf,t,2),0)
v2a#=VertexV(surf,TriangleVertex(surf,t,2),0)
u2b#=VertexU(surf,TriangleVertex(surf,t,2),1)
v2b#=VertexV(surf,TriangleVertex(surf,t,2),1)
nx2#=VertexNX(surf,TriangleVertex(surf,t,2))
ny2#=VertexNY(surf,TriangleVertex(surf,t,2))
nz2#=VertexNZ(surf,TriangleVertex(surf,t,2))
v2_r#=VertexRed(surf,TriangleVertex(surf,t,2))
v2_g#=VertexGreen(surf,TriangleVertex(surf,t,2))
v2_b#=VertexBlue(surf,TriangleVertex(surf,t,2))
v2_a#=VertexAlpha(surf,TriangleVertex(surf,t,2))
vv0=AddVertex(surf2,x0,y0,z0)
VertexTexCoords surf2,vv0,u0a,v0a,0,0
VertexTexCoords surf2,vv0,u0b,v0b,0,1
VertexColor surf2,vv0,v0_r,v0_g,v0_b,v0_a
VertexNormal surf2,vv0,nx0,ny0,nz0
vv1=AddVertex(surf2,x1,y1,z1)
VertexTexCoords surf2,vv1,u1a,v1a,0,0
VertexTexCoords surf2,vv1,u1b,v1b,0,1
VertexColor surf2,vv1,v1_r,v1_g,v1_b,v1_a
VertexNormal surf2,vv1,nx1,ny1,nz1
vv2=AddVertex(surf2,x2,y2,z2)
VertexTexCoords surf2,vv2,u2a,v2a,0,0
VertexTexCoords surf2,vv2,u2b,v2b,0,1
VertexColor surf2,vv2,v2_r,v2_g,v2_b,v2_a
VertexNormal surf2,vv2,nx2,ny2,nz2
tri=AddTriangle(surf2,vv0,vv1,vv2)
Next
Next
FreeEntity mesh
Return mesh2
End Function
;, ********************************************************************************************************************************
End
; freborgs pickedu und pickedv functions
;
; PickedU(), PickedV(), PickedW() commands
;
; Created by Mikkel Fredborg
;
; Use as you please, but please include a thank you :)
;
;
;
; Returns the Texture U coordinate of the last successful pick command
; coordset may be set to either 0 or 1
Function PickedU#(coordset = 0)
; if something new has been picked then calculate the new uvw coordinates
If (PickedX()<>ptri\px) Or (PickedY()<>ptri\py) Or (PickedZ()<>ptri\pz) Or (PickedSurface()<>ptri\surf)
PickedUVW()
End If
Return ptri\pu[coordset]
End Function
;
; Returns the Texture U coordinate of the last successful pick command
; coordset may be set to either 0 or 1
Function PickedV#(coordset = 0)
; if something new has been picked then calculate the new uvw coordinates
If (PickedX()<>ptri\px) Or (PickedY()<>ptri\py) Or (PickedZ()<>ptri\pz) Or (PickedSurface()<>ptri\surf)
PickedUVW()
End If
Return ptri\pv[coordset]
End Function
;
; Returns the Texture U coordinate of the last successful pick command
; coordset may be set to either 0 or 1
Function PickedW#(coordset = 0)
; if something new has been picked then calculate the new uvw coordinates
If (PickedX()<>ptri\px) Or (PickedY()<>ptri\py) Or (PickedZ()<>ptri\pz) Or (PickedSurface()<>ptri\surf)
PickedUVW()
End If
Return ptri\pw[coordset]
End Function
;
; Calculates the UVW coordinates of a pick
; Do not call this by yourself, as PickedU(), PickedV(), and PickedW()
; takes care of calling it when nescessary
Function PickedUVW()
If PickedSurface()
ptri\ent = PickedEntity()
ptri\surf = PickedSurface()
ptri\tri = PickedTriangle()
ptri\px = PickedX()
ptri\py = PickedY()
ptri\pz = PickedZ()
For i = 0 To 2
TFormPoint VertexX(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i)),VertexY(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i)),VertexZ(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i)),ptri\ent,0
ptri\vx[i] = TFormedX()
ptri\vy[i] = TFormedY()
ptri\vz[i] = TFormedZ()
ptri\vnx[i] = VertexNX(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i))
ptri\vny[i] = VertexNY(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i))
ptri\vnz[i] = VertexNZ(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i))
ptri\vu[i+0] = VertexU(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i),0)
ptri\vv[i+0] = VertexV(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i),0)
ptri\vw[i+0] = VertexW(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i),0)
ptri\vu[i+3] = VertexU(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i),1)
ptri\vv[i+3] = VertexV(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i),1)
ptri\vw[i+3] = VertexW(ptri\surf,TriangleVertex(ptri\surf,ptri\tri,i),1)
Next
; Select which component of xyz coordinates to ignore
Local coords = 3
If Abs(PickedNX()) > Abs(PickedNY())
If Abs(PickedNX())>Abs(PickedNZ()) Then coords = 1
Else
If Abs(PickedNY())>Abs(PickedNZ()) Then coords = 2
EndIf
Local a0#,a1#,b0#,b1#,c0#,c1#
; xy components
If (coords = 3)
; edge 0
a0# = ptri\vx[1] - ptri\vx[0]
a1# = ptri\vy[1] - ptri\vy[0]
; edge 1
b0# = ptri\vx[2] - ptri\vx[0]
b1# = ptri\vy[2] - ptri\vy[0]
; picked offset from triangle vertex 0
c0# = PickedX() - ptri\vx[0]
c1# = PickedY() - ptri\vy[0]
Else
; xz components
If (coords = 2)
; edge 0
a0# = ptri\vx[1] - ptri\vx[0]
a1# = ptri\vz[1] - ptri\vz[0]
; edge 1
b0# = ptri\vx[2] - ptri\vx[0]
b1# = ptri\vz[2] - ptri\vz[0]
; picked offset from triangle vertex 0
c0# = PickedX() - ptri\vx[0]
c1# = PickedZ() - ptri\vz[0]
Else
; yz components
; edge 0
a0# = ptri\vy[1] - ptri\vy[0]
a1# = ptri\vz[1] - ptri\vz[0]
; edge 1
b0# = ptri\vy[2] - ptri\vy[0]
b1# = ptri\vz[2] - ptri\vz[0]
; picked offset from triangle vertex 0
c0# = PickedY() - ptri\vy[0]
c1# = PickedZ() - ptri\vz[0]
End If
End If
;
; u and v are offsets from vertex 0 along edge 0 and edge 1
; using these it is possible to calculate the Texture UVW coordinates
; of the picked XYZ location
;
; a0*u + b0*v = c0
; a1*u + b1*v = c1
;
; solve equation (standard equation with 2 unknown quantities)
; check a math book to see why the following is true
;
Local u# = (c0*b1 - b0*c1) / (a0*b1 - b0*a1)
Local v# = (a0*c1 - c0*a1) / (a0*b1 - b0*a1)
; If either u or v is out of range then the
; picked entity was not a mesh, and therefore
; the uvw coordinates cannot be calculated
If (u<0.0 Or u>1.0) Or (v<0.0 Or v>1.0)
Return
End If
; Calculate picked uvw's for coordset 0 (and modulate them to be in the range of 0-1 nescessary)
ptri\pu[0] = (ptri\vu[0] + ((ptri\vu[1] - ptri\vu[0]) * u) + ((ptri\vu[2] - ptri\vu[0]) * v)) Mod 1
ptri\pv[0] = (ptri\vv[0] + ((ptri\vv[1] - ptri\vv[0]) * u) + ((ptri\vv[2] - ptri\vv[0]) * v)) Mod 1
ptri\pw[0] = (ptri\vw[0] + ((ptri\vw[1] - ptri\vw[0]) * u) + ((ptri\vw[2] - ptri\vw[0]) * v)) Mod 1
; If any of the coords are negative
If ptri\pu[0]<0.0 Then ptri\pu[0] = 1.0 + ptri\pu[0]
If ptri\pv[0]<0.0 Then ptri\pv[0] = 1.0 + ptri\pv[0]
If ptri\pw[0]<0.0 Then ptri\pw[0] = 1.0 + ptri\pw[0]
; Calculate picked uvw's for coordset 1 (and modulate them to be in the range of 0-1 nescessary)
ptri\pu[1] = (ptri\vu[3] + ((ptri\vu[4] - ptri\vu[3]) * u) + ((ptri\vu[5] - ptri\vu[3]) * v)) Mod 1
ptri\pv[1] = (ptri\vv[3] + ((ptri\vv[4] - ptri\vv[3]) * u) + ((ptri\vv[5] - ptri\vv[3]) * v)) Mod 1
ptri\pw[1] = (ptri\vw[3] + ((ptri\vw[4] - ptri\vw[3]) * u) + ((ptri\vw[5] - ptri\vw[3]) * v)) Mod 1
; If any of the coords are negative
If ptri\pu[1]<0.0 Then ptri\pu[1] = 1.0 + ptri\pu[1]
If ptri\pv[1]<0.0 Then ptri\pv[1] = 1.0 + ptri\pv[1]
If ptri\pw[1]<0.0 Then ptri\pw[1] = 1.0 + ptri\pw[1]
End If
End Function
End
;
; Test example for
; PickedU(),PickedV(),PickedW() commands
;
; Created by Mikkel Fredborg
; Inspired by David Bird
;
Graphics3D 640,480
SetBuffer BackBuffer()
lit=CreateLight()
LightColor lit,60,60,60
PositionEntity lit,0,10,0
RotateEntity lit,90,0,0
cam=CreateCamera()
CameraRange cam,.1,1000
PositionEntity cam,0,0,-3
CameraClsColor cam,100,100,100
cubetex=CreateTexture(64,64)
; make some squares on the texture
SetBuffer TextureBuffer(cubetex)
Color 128,128,128
Rect 0,0,TextureWidth(cubetex)/2.0,TextureHeight(cubetex)/2.0,True
Rect TextureWidth(cubetex)/2.0,TextureHeight(cubetex)/2.0,(TextureWidth(cubetex)/2.0)-1,(TextureHeight(cubetex)/2.0)-1,True
SetBuffer BackBuffer()
cube = CreateCube()
PositionEntity cube,1,0,0
EntityTexture cube,cubetex,0,0
EntityPickMode cube,2
; Adjust uv coordinates of the cube to tile the texture
surf_n = CountSurfaces(cube)
For i = 1 To surf_n
surf = GetSurface(cube,i)
n_verts = CountVertices(surf)-1
For j = 0 To n_verts
VertexTexCoords surf,j,VertexU(surf,j)*5.0,VertexV(surf,j)*5.0,VertexW(surf,j)*5.0
Next
Next
spheretex=CreateTexture(256,256)
sphere = CreateSphere()
PositionEntity sphere,-1,0,0
EntityTexture sphere,spheretex,0,0
EntityPickMode sphere,2
plane = CreatePlane()
PositionEntity plane,0,-2,0
EntityPickMode plane,2
Global dotred# = 0.0
Global dotgrn# = 0.0
Global dotblu# = 0.0
ang# = 0
While Not KeyDown(1)
xm = MouseX()
ym = MouseY()
If MouseDown(1) Then
Select CameraPick(cam,xm,ym)
Case cube: PaintRedDot(cubetex ,PickedU()*(TextureWidth(cubetex)-1) ,PickedV()*(TextureHeight(cubetex)-1))
Case sphere: PaintRedDot(spheretex,PickedU()*(TextureWidth(spheretex)-1),PickedV()*(TextureHeight(spheretex)-1))
End Select
Else
If MouseDown(2) Then
Select CameraPick(cam,xm,ym)
Case cube: ReadDot(cubetex ,PickedU()*(TextureWidth(cubetex)-1) ,PickedV()*(TextureHeight(cubetex)-1))
Case sphere: ReadDot(spheretex,PickedU()*(TextureWidth(spheretex)-1),PickedV()*(TextureHeight(spheretex)-1))
End Select
End If
End If
ang = (ang + 0.1) Mod 360
TurnEntity cube,-Sin(ang)*0.3,-Cos(ang)*0.3,0
TurnEntity sphere,Sin(ang)*0.1,Cos(ang)*0.1,0
UpdateWorld
RenderWorld
; draw mouse cursor
Line xm-8,ym,xm-4,ym
Line xm+8,ym,xm+4,ym
Line xm,ym-8,xm,ym-4
Line xm,ym+8,xm,ym+4
Oval xm-4,ym-4,9,9,False
; write some info
Text 0, 0,"Use left mousebutton to paint the cube and the sphere"
Text 0, 20,"ent = "+PickedEntity()
Text 0, 35,"surf = "+PickedSurface()
Text 0, 50,"tri = "+PickedTriangle()
Text 0, 80,"x = "+PickedX()
Text 0, 95,"y = "+PickedY()
Text 0,110,"z = "+PickedZ()
Text 0,140,"u = "+PickedU()
Text 0,155,"v = "+PickedV()
Text 0,170,"w = "+PickedW()
Text 0,200,"nx= "+PickedNX()
Text 0,215,"ny= "+PickedNY()
Text 0,230,"nz= "+PickedNZ()
Text 14,460,"Use right mousebutton to pick up a texture color"
Color dotred,dotgrn,dotblu
Rect 0,460,12,12,True
Color 255,255,255
Flip
Wend
ClearWorld
End
;
; Plots a red dot :)
Function PaintRedDot(tex,x,y)
SetBuffer TextureBuffer(tex)
maxwidth = TextureWidth(tex)
maxheight = TextureHeight(tex)
red# = 255
grn# = 0
blu# = 0
WritePixel x,y,blu Or (grn Shl 8) Or (red Shl 16)
For xx = -1 To 1
For yy = -1 To 1
If (xx=0) Xor (yy=0)
If (xx<0 And x>0) Or (xx>0 And x<maxwidth) Or (yy<0 And y>0) Or (yy>0 And y<maxheight)
argb = ReadPixel(x+xx,y+yy)
red# = 64 + (argb Shr 16 And %11111111)
grn# = 0 + (argb Shr 8 And %11111111)
blu# = 0 + (argb Shr 8 And %11111111)
If red>255 Then red = 255
If grn>255 Then grn = 255
If blu>255 Then blu = 255
WritePixel x+xx,y+yy,blu Or (grn Shl 8) Or (red Shl 16)
End If
End If
Next
Next
SetBuffer BackBuffer()
End Function
;
; Reads a pixel in a texture
Function ReadDot(tex,x,y)
SetBuffer TextureBuffer(tex)
maxwidth = TextureWidth(tex)
maxheight = TextureHeight(tex)
If x<maxwidth And y<maxheight
argb = ReadPixel(x,y)
dotred# = (argb Shr 16 And %11111111)
dotgrn# = (argb Shr 8 And %11111111)
dotblu# = (argb Shr 8 And %11111111)
End If
SetBuffer BackBuffer()
End Function
; end of freborgs pickedu / pickedv functions
Function csp_lima_minrel#(mesh,texsize)
; gives relation between biggest triangle side and texture size...
msize#=0
surfs=CountSurfaces(mesh)
For s=1 To surfs
surf=GetSurface(mesh,s)
tris=CountTriangles(surf)
For t=0 To tris-1
x0#=VertexX(surf,TriangleVertex(surf,t,0))
y0#=VertexY(surf,TriangleVertex(surf,t,0))
z0#=VertexZ(surf,TriangleVertex(surf,t,0))
x1#=VertexX(surf,TriangleVertex(surf,t,1))
y1#=VertexY(surf,TriangleVertex(surf,t,1))
z1#=VertexZ(surf,TriangleVertex(surf,t,1))
x2#=VertexX(surf,TriangleVertex(surf,t,2))
y2#=VertexY(surf,TriangleVertex(surf,t,2))
z2#=VertexZ(surf,TriangleVertex(surf,t,2))
x0n#=VertexNX(surf,TriangleVertex(surf,t,0))
y0n#=VertexNY(surf,TriangleVertex(surf,t,0))
z0n#=VertexNZ(surf,TriangleVertex(surf,t,0))
x1n#=VertexNX(surf,TriangleVertex(surf,t,1))
y1n#=VertexNY(surf,TriangleVertex(surf,t,1))
z1n#=VertexNZ(surf,TriangleVertex(surf,t,1))
x2n#=VertexNX(surf,TriangleVertex(surf,t,2))
y2n#=VertexNY(surf,TriangleVertex(surf,t,2))
z2n#=VertexNZ(surf,TriangleVertex(surf,t,2))
xsize#=max3(x0,x1,x2)-min3(x0,x1,x2)
ysize#=max3(y0,y1,y2)-min3(y0,y1,y2)
zsize#=max3(z0,z1,z2)-min3(z0,z1,z2)
size#=max3(xsize,ysize,zsize)
If size>msize Then msize=size
Next
Next
rel#=Float(texsize)/msize
Return rel
End Function
Function csp_CreateHelperQuad()
Local mesh
mesh=CreateMesh()
b=CreateBrush(255,0,255)
surface=CreateSurface(mesh,b)
v0= AddVertex(surface,-1, 1,0)
v1= AddVertex(surface, 1, 1,0)
v2= AddVertex(surface, 1,-1,0)
v3= AddVertex(surface,-1,-1,0)
AddTriangle surface,v0,v1,v3
AddTriangle surface,v1,v2,v3
RotateMesh mesh,0,180,0
ScaleMesh mesh,100,100,0
;EntityFX mesh,16
Return mesh
End Function
; creates a dummy scene mesh with several materials
Function csp_MyCreateDummyMap()
Local mesh
s=128
ttex=CreateTexture(s,s,4)
SetBuffer TextureBuffer(ttex)
LockBuffer()
For j = 0 To s-1
For i = 0 To s-1
a=(((i) And 31)*8)-1
g=255
rgb=(a Shl 24) Or (g Shl 16) Or (g Shl 8) Or (g)
WritePixelFast i,j,rgb
Next
Next
UnlockBuffer()
SetBuffer workbuffer
s=128
ttex2=CreateTexture(s,s,3 Or 512)
SetBuffer TextureBuffer(ttex2)
LockBuffer()
For j = 0 To s-1
For i = 0 To s-1
a=127+j ;((i Or j)*4) And $255
g=255
rgb=(a Shl 24) Or (g Shl 16) Or (g Shl 8) Or (g)
WritePixelFast i,j,rgb
Next
Next
UnlockBuffer()
SetBuffer workbuffer
mesh=CreateCylinder()
brush1=CreateBrush(255,0,0)
BrushTexture brush1,ttex
PaintMesh mesh, brush1
ground=CreateCube()
ScaleMesh ground,4,0.1,4
PositionMesh ground,0,-.3,0
sp=CreateSphere()
PositionMesh sp,-2,0.5,2
brush2=CreateBrush(0,255,0)
;brush2=CreateBrush(255,255,255)
;ttex2=LoadTexture("test_alpha.bmp",2 Or 512)
;BrushTexture brush2,ttex2
;BrushBlend brush2,3
;BrushAlpha brush2,0.999999
PaintMesh sp, brush2
AddMesh sp,mesh
AddMesh ground, mesh
;UpdateNormals mesh
FreeEntity sp
FreeEntity ground
Return mesh
End Function