--Создание и настройка окна программы
window_handle = WindowsCreate("Example: 'bump-shadows'",WS_OVERLAPPED,WS_SYSMENU,0,32,32,1280,720,0)
WindowCenter(window_handle)
WindowSetIcon(window_handle,"Logo.ico")

--Инициализация движков программы
Init_xtreme3d("xtreme3d.dll") --Графический

--Настройка компонентов графического движка
xEngineCreate()

matlib=xMaterialLibraryCreate()
xMaterialLibraryActivate(matlib)

bgColor = c_Gray
view1=xViewerCreate(0,0,1280,720,window_handle)
xViewerSetBackgroundColor(view1,bgColor)
xViewerSetLighting(view1,1)
xViewerEnableFog(view1,1)
xViewerSetFogColor(view1,bgColor)
xViewerSetFogDistance(view1,100,200)
xViewerSetAntiAliasing(view1, aa4xHQ)
xViewerSetAutoRender(view1, False)
rendering = True

back=xDummycubeCreate(0)
scene=xDummycubeCreate(0)
postscene=xDummycubeCreate(0)
front=xDummycubeCreate(0)

camPos=xDummycubeCreate(scene)
xObjectSetPosition(camPos,2,1,0)
xObjectTurn(camPos, -90)
moving = False

camera=xCameraCreate(camPos)
xCameraSetViewDepth(camera,500)
xCameraSetFocal(camera, 80)
xCameraSetNearPlaneBias(camera, 0.2)
xViewerSetCamera(view1,camera)

shadowCasters = xDummycubeCreate(scene)

shadowCam = xCameraCreate(scene)
xCameraSetViewDepth(shadowCam, 500)
target = xDummycubeCreate(scene)
xObjectSetPosition(target, 0, -1, 0)
xCameraSetTargetObject(shadowCam, target)
xObjectSetPosition(shadowCam, 0, 10, 0)
xObjectPitch(shadowCam, -70)
xObjectTurn(shadowCam, -20)
    
shadowRes = 1024
sm = xShadowMapCreate(shadowRes, view1, shadowCasters)
xShadowMapSetCamera(sm, shadowCam)
xShadowMapSetProjectionSize(sm, 5)
xShadowMapSetZClippingPlanes(sm, -10.0, 200.0)

xMaterialCreate('mStoneWallDiffuse', 'data/room/stone.png')
xMaterialCreate('mStoneWallNormal', 'data/room/stone-normal.png')
xMaterialCreate('mStoneWallHeight', 'data/room/stone-height.png')
--Bump shader with shadows for room
bump2 = xBumpShaderCreate()
xBumpShaderSetDiffuseTexture(bump2, 'mStoneWallDiffuse')
xBumpShaderSetNormalTexture(bump2, 'mStoneWallNormal')
xBumpShaderSetHeightTexture(bump2, 'mStoneWallHeight')
xBumpShaderSetMaxLights(bump2, 3)
xBumpShaderUseParallax(bump2, True)
xBumpShaderSetShadowMap(bump2, sm)
xBumpShaderSetShadowBlurRadius(bump2, 2)

col_ambient = RGB(48,48,48) --Полинился делать функцию

xMaterialCreate('mStoneWall', '')
xMaterialSetShininess('mStoneWall', 32)
xMaterialSetAmbientColor('mStoneWall', RGB(32,32,32) , 1)
xMaterialSetDiffuseColor('mStoneWall', cWhite, 1)
xMaterialSetSpecularColor('mStoneWall', cGray, 1)
xMaterialSetShader('mStoneWall', bump2)

ffm = xFreeformCreate('data/room/room.b3d', matlib, matlib, scene)
xFreeformGenTangents(ffm)
xObjectSetMaterial(ffm, 'mStoneWall')
xFreeformUseMeshMaterials(ffm, False)

--Auto tangent map shader with parallax mapping for primitives
bump3 = xBumpShaderCreate()
xBumpShaderSetDiffuseTexture(bump3, 'mStoneWallDiffuse')
xBumpShaderSetNormalTexture(bump3, 'mStoneWallNormal')
xBumpShaderSetHeightTexture(bump3, 'mStoneWallHeight')
xBumpShaderSetMaxLights(bump3, 3)
xBumpShaderUseParallax(bump3, True)
xBumpShaderSetShadowMap(bump3, sm)
xBumpShaderSetShadowBlurRadius(bump3, 2)
xBumpShaderUseAutoTangentSpace(bump3, True)

xMaterialCreate('mStoneWall2', '')
xMaterialSetShininess('mStoneWall2', 32)
xMaterialSetAmbientColor('mStoneWall2', col_ambient, 1)
xMaterialSetDiffuseColor('mStoneWall2', cWhite, 1)
xMaterialSetSpecularColor('mStoneWall2', cGray, 1)
xMaterialSetShader('mStoneWall2', bump3)

sphere = xSphereCreate(0.25, 16, 8, shadowCasters)
xObjectSetPosition(sphere, 1, 0.25, 1)
xObjectSetMaterial(sphere, 'mStoneWall2')
    
cylinder = xCylinderCreate(0.25, 0.25, 0.5, 16, 4, 1, shadowCasters)
xObjectSetPosition(cylinder, -1, 0.25, 1)
xObjectSetMaterial(cylinder, 'mStoneWall2')

torus = xTorusCreate(0.1, 0.25, 16, 8, shadowCasters) 
xObjectSetPosition(torus, 0, 0.25, 1)
xObjectPitch(torus, 90)
xObjectSetMaterial(torus, 'mStoneWall2')
    
matlib2 = xMaterialLibraryCreate()
xMaterialLibrarySetTexturePaths(matlib2, 'data/hellknight') 
xMaterialLibraryActivate(matlib2)
--Auto tangent map shader for hellknight
bump = xBumpShaderCreate()
xBumpShaderSetDiffuseTexture(bump, '')
xBumpShaderSetNormalTexture(bump, '')
xBumpShaderSetMaxLights(bump, 3)
xBumpShaderSetShadowMap(bump, sm)
xBumpShaderSetShadowBlurRadius(bump, 2)
xBumpShaderUseAutoTangentSpace(bump, True)
xMaterialCreate('mHellknight', 'diffuse.png')
xMaterialCreate('mHellknightNormal', 'normal.png')
xMaterialSetSecondTexture('mHellknight', 'mHellknightNormal')
xMaterialSetShininess('mHellknight', 32)
xMaterialSetAmbientColor('mHellknight', col_ambient, 1)
xMaterialSetDiffuseColor('mHellknight', cWhite, 1)
xMaterialSetSpecularColor('mHellknight', cGray, 1)
xMaterialSetShader('mHellknight', bump)

hk = xActorCreate('data/hellknight/hellknight.md5mesh', matlib2, shadowCasters)
xActorAddObject(hk, 'data/hellknight/idle2.md5anim')
xActorAddObject(hk, 'data/hellknight/attack2.md5anim')
xActorSwitchToAnimation(hk, 0, True)
xObjectSetScale(hk, 0.012, 0.012, 0.012)
xObjectSetPosition(hk, 0, 0, 0)
xObjectSetMaterial(hk, 'mHellknight')
    
xMaterialLibraryActivate(matlib)

xMaterialCreate('mFlare', 'data/flare.png')
xMaterialSetOptions('mFlare', True, True)
xMaterialSetBlendingMode('mFlare', bmAdditive)
movingObject = xDummycubeCreate(scene)
xObjectSetPosition(movingObject, 2, 1.5, 2)
spr = xSpriteCreate('mFlare', 0.7, 0.7, movingObject)
tr = xTrailCreate(movingObject, scene) 
xTrailSetMarkWidth(tr, 0.1)
xTrailSetLimits(tr, 300, 1.0)

m = xMovementCreate(movingObject)
pa = xMovementAddPath(m)
node = xMovementPathAddNode(pa)
xMovementPathNodeSetPosition(node, 2, 1.5, 2)
node = xMovementPathAddNode(pa)
xMovementPathNodeSetPosition(node, -2, 1.5, 2)
node = xMovementPathAddNode(pa)
xMovementPathNodeSetPosition(node, -2, 0.5, -2)
    
pa2 = xMovementAddPath(m)
node = xMovementPathAddNode(pa2)
xMovementPathNodeSetPosition(node, -2, 0.5, -2)
node = xMovementPathAddNode(pa2)
xMovementPathNodeSetPosition(node, 2, 0.5, -2)
node = xMovementPathAddNode(pa2)
xMovementPathNodeSetPosition(node, 2, 1.5, 2)

xMovementSetActivePath(m, 0)
xMovementAutoStartNextPath(m, True)
xMovementStart(m)

light=xLightCreate(lsOmni, scene)
xLightSetAmbientColor(light,cBlack, 1.0)
xLightSetDiffuseColor(light,cYellow, 1.0)
xLightSetSpecularColor(light,cYellow, 1.0)
xLightSetAttenuation(light, 1, 0.3, 0.0)
xObjectSetPosition(light,-2,1,-2)

light2=xLightCreate(lsOmni, scene)
xLightSetAmbientColor(light2,cBlack, 1.0)
xLightSetDiffuseColor(light2,cAqua, 1.0)
xLightSetSpecularColor(light2,cAqua, 1.0)
xLightSetAttenuation(light2, 1, 0.3, 0.0)
xObjectSetPosition(light2,-2,1,2)

light3=xLightCreate(lsOmni, movingObject)
xLightSetAmbientColor(light3,cBlack, 1.0)
xLightSetDiffuseColor(light3,cGray, 1.0)
xLightSetSpecularColor(light3,cGray, 1.0)
xLightSetAttenuation(light3, 1, 0.3, 0.0)

mx=DisplayGetParemeter(0)/2
my=DisplayGetParemeter(1)/2
DisplayMouseSet(mx,my)

font=xWindowsBitmapfontCreate('Arial',20,0,128)
text=xHUDTextCreate(font,'Xtreme3D 3.5'..string.char(13)..'FPS: ',front)
xHUDTextSetColor(text,cWhite,0.5)
xObjectSetPosition(text,20,20,0)

paused=0
pressed_end=0
screenNum = 0

while WindowsExists(window_handle) do
	WindowsRefresh()
	KeyRefresh()
	fps = CallFps(60)
	dt = 1/fps
	
	if paused == 0 then
		deltax=(mx-DisplayMouseGet(0))/3
		deltay=(my-DisplayMouseGet(1))/3
		xObjectRotate(camera,deltay,0,0)
		xObjectRotate(camPos,0,-deltax,0)
		DisplayMouseSet(mx,my)
		
		if Key(string.byte('W')) then xObjectMove(camPos,-2*dt) end
		if Key(string.byte('A')) then xObjectStrafe(camPos,2*dt) end
		if Key(string.byte('D')) then xObjectStrafe(camPos,-2*dt) end
		if Key(string.byte('S')) then xObjectMove(camPos,2*dt) end
	end
	
	xObjectSetPositionOfObject(shadowCam, movingObject)
	
	framerate=math.floor(xViewerGetFramesPerSecond(view1))
	xHUDTextSetText(text,'Xtreme3D 3.5'..string.char(13)..'FPS: '..framerate..string.char(13)..'Press <Enter> to restart light movement')
	
	xUpdate(dt)
	
	xObjectHide(front)
	xShadowMapRender(sm)
	xObjectShow(front)
	
	xViewerRender(view1)
	
	if KeyReleased(VK_RETURN) then
		xMovementSetActivePath(m,0) 
		xMovementStart(m)
	end
	
	if KeyReleased(VK_ESCAPE) then WindowsDestroy(window_handle) end
	
	if KeyReleased(VK_F12) then --Делаем снимок экрана
		screenNum = screenNum + 1
		saved = false
		while not saved do
			str = 'screenshots/screenshot'..screenNum..'.bmp'
			if not FileExists(str) then
				xViewerRenderToFile(view1, str)
				saved = true
			else screenNum = screenNum + 1 end
		end
	end
end

--EngineDestroy()