// Hide GM window
draw_enable_drawevent(false);
application_surface_draw_enable(false);

// Initialize Xtreme3D
dll_init("xtreme3d.dll");

EngineCreate();
EngineShowLoadingErrors(true);
EngineSetCulling(vcNone);
EngineSetObjectsSorting(osNone);
EngineSetMaxLights(8);

// Create custom window
window = WindowCreate(0, 0, 1280, 720, false);
WindowSetTitle(window, "Xtreme3D 4 Water Demo");
WindowCenter(window);

var x3dPath = environment_get_variable("userprofile") + "/Xtreme3D";
if (not directory_exists(x3dPath)) {
	directory_create(x3dPath);
}

logger = LoggerCreate(x3dPath + "/xtreme3d.log", llMax);

// Create viewer in the game window
windowHandle = WindowGetHandle(window);
viewer = ViewerCreate(0, 0, 1280, 720, windowHandle);
ViewerSetBackgroundColor(viewer, c_black);
ViewerSetLighting(viewer, true);
ViewerEnableFog(viewer, false);
ViewerSetFogColor(viewer, c_gray);
ViewerSetFogDistance(viewer, 0, 50);
ViewerSetAntiAliasing(viewer, csa8xHQ); //CSAA
ViewerEnableVSync(viewer, vsmSync); 
ViewerSetAutoRender(viewer, false);

// Create main material library
matlib = MaterialLibraryCreate();
MaterialLibraryActivate(matlib);

// Create root scene objects
global.preprocess = DummycubeCreate(0);
global.backscene = DummycubeCreate(0);
global.back = DummycubeCreate(global.backscene);
global.scene = DummycubeCreate(global.backscene);
global.front = DummycubeCreate(0);

MaterialCreate("mSkyTop", "data/sky/sky_top.tga");
MaterialCreate("mSkyBottom", "data/sky/sky_bottom.tga");
MaterialCreate("mSkyLeft", "data/sky/sky_left.tga");
MaterialCreate("mSkyRight", "data/sky/sky_right.tga");
MaterialCreate("mSkyFront", "data/sky/sky_front.tga");
MaterialCreate("mSkyBack", "data/sky/sky_back.tga");
sky = SkyboxCreate(global.back);
SkyboxSetMaterial(sky, sbmTop, "mSkyTop");
SkyboxSetMaterial(sky, sbmBottom, "mSkyBottom");
SkyboxSetMaterial(sky, sbmLeft, "mSkyLeft");
SkyboxSetMaterial(sky, sbmRight, "mSkyRight");
SkyboxSetMaterial(sky, sbmFront, "mSkyFront");
SkyboxSetMaterial(sky, sbmBack, "mSkyBack");

light1 = LightCreate(lsParallel, global.scene);
ObjectPitch(light1, -135);
LightSetAmbientColor(light1, c_black);
LightSetDiffuseColor(light1, c_white);
LightSetSpecularColor(light1, c_white);
ObjectSetPosition(light1, 3, 5, 3);

// Create camera
camPos = DummycubeCreate(global.scene);
ObjectSetPosition(camPos, 0, 0, 3);

camera = CameraCreate(camPos);
ViewerSetCamera(viewer, camera);
ObjectSetPosition(camera, 0, 2, 0);
CameraSetViewDepth(camera, 1000);
CameraSetFocal(camera, 100);
CameraSetNearPlaneBias(camera, 0.2);

reflectionCamera = CameraCreate(camPos);
ObjectSetPosition(reflectionCamera, 0, -2, 0);
CameraSetViewDepth(reflectionCamera, 1000);
CameraSetFocal(reflectionCamera, 100);
CameraSetNearPlaneBias(reflectionCamera, 0.2);

reflectionPlane = ClipPlaneCreate(global.scene);
ClipPlaneSetPlane(reflectionPlane, 0, -0.1, 0, 0, 1, 0);

fboWidth = 1280;
fboHeight = 720;

waterFboMatlib = MaterialLibraryCreate();
MaterialLibraryActivate(waterFboMatlib);

MaterialCreate("reflectionColor", "");
MaterialSetOptions("reflectionColor", true, true);
MaterialGenTexture("reflectionColor", fboWidth, fboHeight);
MaterialSetTextureFormat("reflectionColor", tfExtended);
MaterialSetTextureFormatEx("reflectionColor", tfRGBA8);
MaterialSetTextureFilter("reflectionColor", miLinear, maLinear);
MaterialSetTextureWrap("reflectionColor", twSeparate);
MaterialSetTextureWrapS("reflectionColor", twClampToEdge);
MaterialSetTextureWrapT("reflectionColor", twClampToEdge);

MaterialCreate("reflectionDepth", "");
MaterialSetOptions("reflectionDepth", true, true);
MaterialGenTexture("reflectionDepth", fboWidth, fboHeight);
MaterialSetTextureFormat("reflectionDepth", tfExtended);
MaterialSetTextureFormatEx("reflectionDepth", tfDEPTH_COMPONENT24);
MaterialSetTextureWrap("reflectionDepth", twSeparate);
MaterialSetTextureWrapS("reflectionDepth", twClampToBorder);
MaterialSetTextureWrapT("reflectionDepth", twClampToBorder);
MaterialSetTextureBorderColor("reflectionDepth", c_white);
MaterialSetTextureFilter("reflectionDepth", miLinear, maLinear);

reflectionFbo = FBOCreate(fboWidth, fboHeight, global.preprocess);
FBOSetMaterialLibrary(reflectionFbo, waterFboMatlib);
FBOSetCamera(reflectionFbo, reflectionCamera);
FBOSetAspect(reflectionFbo, 1.0);
FBOSetBackgroundColor(reflectionFbo, c_green);
FBOSetRootObject(reflectionFbo, global.backscene);
FBOSetColorTextureName(reflectionFbo, "reflectionColor");
FBOSetDepthTextureName(reflectionFbo, "reflectionDepth");
FBOSetTargetVisibility(reflectionFbo, tvDefault);
FBOSetClearOptions(reflectionFbo, true, true, true, true);
FBOSetEnabledRenderBuffers(reflectionFbo, true, false);
FBOSetActive(reflectionFbo, true);

MaterialCreate("mWaterNormal1", "data/water/water-norm-001.png");
MaterialCreate("mWaterNormal2", "data/water/water-norm-002.png");

MaterialCreate("mWater", "");
MaterialSetOptions("mWater", true, true);
MaterialSetBlendingMode("mWater", bmTransparency);

waterVertexProgram = TextRead("shaders/water-vp.glsl");
waterFragmentProgram = TextRead("shaders/water-fp.glsl");

waterShader = GLSLShaderCreate(waterVertexProgram, waterFragmentProgram);
GLSLShaderSetLogger(waterShader, logger);

waterParamReflectionMap = GLSLShaderCreateParameter(waterShader, "reflectionMap");
GLSLShaderSetParameterTexture(waterParamReflectionMap, "reflectionColor", 0);

waterParamViewSize = GLSLShaderCreateParameter(waterShader, "viewSize");
GLSLShaderSetParameter2f(waterParamViewSize, fboWidth, fboHeight);

waterParamScrollTime = GLSLShaderCreateParameter(waterShader, "scrollTime");
scrollTime = 0.0;
GLSLShaderSetParameter1f(waterParamScrollTime, scrollTime);

waterParamNormalmap1 = GLSLShaderCreateParameter(waterShader, "normalMap1");
GLSLShaderSetParameterTexture(waterParamNormalmap1, "mWaterNormal1", 3);

waterParamNormalmap2 = GLSLShaderCreateParameter(waterShader, "normalMap2");
GLSLShaderSetParameterTexture(waterParamNormalmap2, "mWaterNormal2", 4);

MaterialSetShader("mWater", waterShader);

waterPlane = PlaneCreate(false, 100, 100, 50, 50, global.scene); 
ObjectPitch(waterPlane, 90);
ObjectSetMaterial(waterPlane, "mWater");

MaterialLibraryActivate(matlib);

levelMatlib = MaterialLibraryCreate();
MaterialLibrarySetTexturePaths(levelMatlib, "data/b3d");
levelFilename = "data/b3d/level.b3d";
ffm = FreeformCreate(levelFilename, levelMatlib, levelMatlib, reflectionPlane);
FreeformBuildOctree(ffm);
ObjectSetPosition(ffm, 0, -0.5, 0);
MaterialLibraryActivate(matlib);

ftfont = TTFontCreate("data/fonts/DroidSans.ttf", 20);
text = HUDTextCreate(ftfont, "FPS: 0", global.front);
HUDTextSetColor(text, c_white, 1.0);
ObjectSetPosition(text, 20, 20, 0);

mouselookActive = false;
mb_left_released = true;
mx = display_get_width() / 2;
my = display_get_height() / 2;
MouseSetPosition(mx, my);

game_set_speed(60, gamespeed_fps);

canTakeScreenshot = true;
