2012-01-23 23:45:33 +00:00
|
|
|
#include "scenery.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2012-01-29 17:39:56 +00:00
|
|
|
#include "color.h"
|
|
|
|
#include "euclid.h"
|
2012-01-24 13:16:20 +00:00
|
|
|
#include "render.h"
|
2012-01-29 17:39:56 +00:00
|
|
|
#include "system.h"
|
2012-01-23 23:45:33 +00:00
|
|
|
|
2012-01-24 15:47:49 +00:00
|
|
|
AtmosphereDefinition _atmosphere;
|
2012-01-23 23:45:33 +00:00
|
|
|
CameraDefinition _camera;
|
|
|
|
CloudsDefinition _clouds;
|
|
|
|
LightingDefinition _lighting;
|
|
|
|
SkyDefinition _sky;
|
|
|
|
TerrainDefinition _terrain;
|
|
|
|
TexturesDefinition _textures;
|
|
|
|
WaterDefinition _water;
|
|
|
|
|
|
|
|
void sceneryInit()
|
|
|
|
{
|
2012-01-24 15:47:49 +00:00
|
|
|
atmosphereInit();
|
2012-01-23 23:45:33 +00:00
|
|
|
cameraInit();
|
|
|
|
cloudsInit();
|
|
|
|
lightingInit();
|
|
|
|
skyInit();
|
|
|
|
terrainInit();
|
|
|
|
texturesInit();
|
|
|
|
waterInit();
|
|
|
|
|
2012-01-24 15:47:49 +00:00
|
|
|
_atmosphere = atmosphereCreateDefinition();
|
2012-01-23 23:45:33 +00:00
|
|
|
_camera = cameraCreateDefinition();
|
|
|
|
_clouds = cloudsCreateDefinition();
|
|
|
|
_lighting = lightingCreateDefinition();
|
|
|
|
_sky = skyCreateDefinition();
|
|
|
|
_terrain = terrainCreateDefinition();
|
|
|
|
_textures = texturesCreateDefinition();
|
|
|
|
_water = waterCreateDefinition();
|
|
|
|
}
|
|
|
|
|
|
|
|
void scenerySaveToFile(char* filepath)
|
|
|
|
{
|
|
|
|
FILE* f = fopen(filepath, "wb");
|
|
|
|
|
2012-01-24 15:47:49 +00:00
|
|
|
atmosphereSave(f, &_atmosphere);
|
2012-01-23 23:45:33 +00:00
|
|
|
cameraSave(f, &_camera);
|
|
|
|
cloudsSave(f, &_clouds);
|
|
|
|
lightingSave(f, &_lighting);
|
|
|
|
skySave(f, &_sky);
|
|
|
|
terrainSave(f, &_terrain);
|
|
|
|
texturesSave(f, &_textures);
|
|
|
|
waterSave(f, &_water);
|
|
|
|
|
2012-01-29 17:39:56 +00:00
|
|
|
fflush(f);
|
2012-01-23 23:45:33 +00:00
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceneryLoadFromFile(char* filepath)
|
|
|
|
{
|
|
|
|
FILE* f = fopen(filepath, "rb");
|
|
|
|
|
|
|
|
/* TODO Use intermediary definitions ? */
|
|
|
|
|
2012-01-24 15:47:49 +00:00
|
|
|
atmosphereLoad(f, &_atmosphere);
|
2012-01-23 23:45:33 +00:00
|
|
|
cameraLoad(f, &_camera);
|
|
|
|
cloudsLoad(f, &_clouds);
|
|
|
|
lightingLoad(f, &_lighting);
|
|
|
|
skyLoad(f, &_sky);
|
|
|
|
terrainLoad(f, &_terrain);
|
|
|
|
texturesLoad(f, &_textures);
|
|
|
|
waterLoad(f, &_water);
|
2012-01-29 11:34:49 +00:00
|
|
|
|
|
|
|
atmosphereValidateDefinition(&_atmosphere);
|
|
|
|
cameraValidateDefinition(&_camera, 0);
|
|
|
|
cloudsValidateDefinition(&_clouds);
|
|
|
|
lightingValidateDefinition(&_lighting);
|
|
|
|
skyValidateDefinition(&_sky);
|
|
|
|
terrainValidateDefinition(&_terrain);
|
|
|
|
texturesValidateDefinition(&_textures);
|
2012-01-23 23:45:33 +00:00
|
|
|
waterValidateDefinition(&_water);
|
|
|
|
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
|
2012-01-24 15:47:49 +00:00
|
|
|
void scenerySetAtmosphere(AtmosphereDefinition* atmosphere)
|
|
|
|
{
|
|
|
|
atmosphereCopyDefinition(atmosphere, &_atmosphere);
|
|
|
|
atmosphereValidateDefinition(&_atmosphere);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceneryGetAtmosphere(AtmosphereDefinition* atmosphere)
|
|
|
|
{
|
|
|
|
atmosphereCopyDefinition(&_atmosphere, atmosphere);
|
|
|
|
}
|
|
|
|
|
2012-01-23 23:45:33 +00:00
|
|
|
void scenerySetCamera(CameraDefinition* camera)
|
|
|
|
{
|
|
|
|
cameraCopyDefinition(camera, &_camera);
|
2012-01-29 11:34:49 +00:00
|
|
|
cameraValidateDefinition(&_camera, 1);
|
2012-01-23 23:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sceneryGetCamera(CameraDefinition* camera)
|
|
|
|
{
|
|
|
|
cameraCopyDefinition(&_camera, camera);
|
|
|
|
}
|
|
|
|
|
|
|
|
void scenerySetClouds(CloudsDefinition* clouds)
|
|
|
|
{
|
|
|
|
cloudsCopyDefinition(clouds, &_clouds);
|
|
|
|
cloudsValidateDefinition(&_clouds);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceneryGetClouds(CloudsDefinition* clouds)
|
|
|
|
{
|
2012-01-24 13:16:20 +00:00
|
|
|
cloudsCopyDefinition(&_clouds, clouds);
|
2012-01-23 23:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void scenerySetLighting(LightingDefinition* lighting)
|
|
|
|
{
|
|
|
|
lightingCopyDefinition(lighting, &_lighting);
|
|
|
|
lightingValidateDefinition(&_lighting);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceneryGetLighting(LightingDefinition* lighting)
|
|
|
|
{
|
|
|
|
lightingCopyDefinition(&_lighting, lighting);
|
|
|
|
}
|
|
|
|
|
|
|
|
void scenerySetSky(SkyDefinition* sky)
|
|
|
|
{
|
|
|
|
skyCopyDefinition(sky, &_sky);
|
|
|
|
skyValidateDefinition(&_sky);
|
|
|
|
|
2012-01-24 15:47:49 +00:00
|
|
|
atmosphereValidateDefinition(&_atmosphere);
|
2012-01-23 23:45:33 +00:00
|
|
|
lightingValidateDefinition(&_lighting);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceneryGetSky(SkyDefinition* sky)
|
|
|
|
{
|
|
|
|
skyCopyDefinition(&_sky, sky);
|
|
|
|
}
|
|
|
|
|
|
|
|
void scenerySetTerrain(TerrainDefinition* terrain)
|
|
|
|
{
|
|
|
|
terrainCopyDefinition(terrain, &_terrain);
|
|
|
|
terrainValidateDefinition(&_terrain);
|
2012-01-29 11:34:49 +00:00
|
|
|
|
|
|
|
cameraValidateDefinition(&_camera, 1);
|
2012-01-23 23:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sceneryGetTerrain(TerrainDefinition* terrain)
|
|
|
|
{
|
|
|
|
terrainCopyDefinition(&_terrain, terrain);
|
|
|
|
}
|
|
|
|
|
|
|
|
void scenerySetTextures(TexturesDefinition* textures)
|
|
|
|
{
|
|
|
|
texturesCopyDefinition(textures, &_textures);
|
|
|
|
texturesValidateDefinition(&_textures);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceneryGetTextures(TexturesDefinition* textures)
|
|
|
|
{
|
|
|
|
texturesCopyDefinition(&_textures, textures);
|
|
|
|
}
|
|
|
|
|
|
|
|
void scenerySetWater(WaterDefinition* water)
|
|
|
|
{
|
|
|
|
waterCopyDefinition(water, &_water);
|
|
|
|
waterValidateDefinition(&_water);
|
2012-01-29 11:34:49 +00:00
|
|
|
|
|
|
|
cameraValidateDefinition(&_camera, 1);
|
2012-01-23 23:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sceneryGetWater(WaterDefinition* water)
|
|
|
|
{
|
|
|
|
waterCopyDefinition(&_water, water);
|
|
|
|
}
|
|
|
|
|
2012-01-24 13:16:20 +00:00
|
|
|
void sceneryRenderFirstPass(Renderer* renderer)
|
|
|
|
{
|
|
|
|
if (!renderSetNextProgressStep(0.0, 0.01))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
skyRender(&_sky, renderer, renderTellProgress);
|
|
|
|
if (!renderSetNextProgressStep(0.01, 0.085))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
terrainRender(&_terrain, renderer, renderTellProgress);
|
|
|
|
if (!renderSetNextProgressStep(0.085, 0.1))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
waterRender(&_water, renderer, renderTellProgress);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sceneryRenderSecondPass(Renderer* renderer)
|
|
|
|
{
|
|
|
|
if (renderSetNextProgressStep(0.1, 1.0))
|
|
|
|
{
|
|
|
|
renderPostProcess(renderer, systemGetCoreCount());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******* Standard renderer *********/
|
|
|
|
static Color _filterLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light)
|
|
|
|
{
|
2012-01-25 17:31:36 +00:00
|
|
|
// TODO atmosphere filter
|
2012-01-24 13:59:54 +00:00
|
|
|
light_color = waterLightFilter(&_water, renderer, light_color, at_location, light_location, direction_to_light);
|
2012-01-25 17:31:36 +00:00
|
|
|
|
|
|
|
return light_color;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Color _maskLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light)
|
|
|
|
{
|
2012-01-24 13:59:54 +00:00
|
|
|
light_color = terrainLightFilter(&_terrain, renderer, light_color, at_location, light_location, direction_to_light);
|
|
|
|
light_color = cloudsFilterLight(&_clouds, renderer, light_color, at_location, light_location, direction_to_light);
|
2012-01-24 13:16:20 +00:00
|
|
|
|
2012-01-24 13:59:54 +00:00
|
|
|
return light_color;
|
2012-01-24 13:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
|
|
|
|
{
|
|
|
|
return lightingApplyToSurface(&_lighting, renderer, location, normal, material);
|
|
|
|
}
|
|
|
|
|
|
|
|
static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds)
|
|
|
|
{
|
|
|
|
RayCastingResult result;
|
2012-01-26 18:20:19 +00:00
|
|
|
Color sky_color;
|
2012-01-24 13:16:20 +00:00
|
|
|
|
|
|
|
if (!terrainProjectRay(&_terrain, renderer, location, direction, &result.hit_location, &result.hit_color))
|
|
|
|
{
|
2012-01-26 18:20:19 +00:00
|
|
|
sky_color = skyGetColor(&_sky, renderer, location, direction);
|
|
|
|
result.hit_location = v3Add(location, v3Scale(direction, 1000.0));
|
|
|
|
result.hit_color = renderer->applyClouds(renderer, sky_color, location, result.hit_location);
|
2012-01-24 13:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
result.hit = 1;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static double _getTerrainHeight(Renderer* renderer, double x, double z)
|
2012-01-23 23:45:33 +00:00
|
|
|
{
|
2012-01-24 13:16:20 +00:00
|
|
|
return terrainGetHeight(&_terrain, x, z);
|
2012-01-23 23:45:33 +00:00
|
|
|
}
|
|
|
|
|
2012-01-29 17:53:12 +00:00
|
|
|
static HeightInfo _getWaterHeightInfo(Renderer* renderer)
|
|
|
|
{
|
|
|
|
return waterGetHeightInfo(&_water);
|
|
|
|
}
|
|
|
|
|
2012-01-24 13:16:20 +00:00
|
|
|
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
2012-01-23 23:45:33 +00:00
|
|
|
{
|
2012-01-24 13:16:20 +00:00
|
|
|
return texturesGetColor(&_textures, renderer, location, precision);
|
2012-01-23 23:45:33 +00:00
|
|
|
}
|
2012-01-24 13:16:20 +00:00
|
|
|
|
|
|
|
static Color _applyAtmosphere(Renderer* renderer, Vector3 location, Color base)
|
|
|
|
{
|
2012-01-24 15:47:49 +00:00
|
|
|
return atmosphereApply(&_atmosphere, renderer, location, base);
|
2012-01-24 13:16:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static Color _applyClouds(Renderer* renderer, Color base, Vector3 start, Vector3 end)
|
|
|
|
{
|
|
|
|
Color clouds;
|
|
|
|
|
|
|
|
clouds = cloudsGetColor(&_clouds, renderer, start, end);
|
|
|
|
colorMask(&base, &clouds);
|
|
|
|
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Vector3 _projectPoint(Renderer* renderer, Vector3 point)
|
|
|
|
{
|
|
|
|
return cameraProject(&_camera, point);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Vector3 _unprojectPoint(Renderer* renderer, Vector3 point)
|
|
|
|
{
|
|
|
|
return cameraUnproject(&_camera, point);
|
|
|
|
}
|
|
|
|
|
|
|
|
static double _getPrecision(Renderer* renderer, Vector3 location)
|
|
|
|
{
|
|
|
|
Vector3 projected;
|
|
|
|
|
|
|
|
projected = cameraProject(&_camera, location);
|
|
|
|
projected.x += 1.0;
|
|
|
|
//projected.y += 1.0;
|
|
|
|
|
|
|
|
return v3Norm(v3Sub(cameraUnproject(&_camera, projected), location)); // / (double)render_quality;
|
|
|
|
}
|
|
|
|
|
|
|
|
Renderer sceneryGetStandardRenderer(int quality)
|
|
|
|
{
|
|
|
|
Renderer result;
|
|
|
|
|
2012-01-24 15:47:49 +00:00
|
|
|
quality = (quality > 10) ? 10 : quality;
|
|
|
|
quality = (quality < 1) ? 1 : quality;
|
|
|
|
|
2012-01-24 13:16:20 +00:00
|
|
|
result.camera_location = _camera.location;
|
|
|
|
result.render_quality = quality;
|
|
|
|
|
|
|
|
result.filterLight = _filterLight;
|
2012-01-25 17:31:36 +00:00
|
|
|
result.maskLight = _maskLight;
|
2012-01-24 13:16:20 +00:00
|
|
|
result.applyLightingToSurface = _applyLightingToSurface;
|
|
|
|
result.rayWalking = _rayWalking;
|
|
|
|
result.getTerrainHeight = _getTerrainHeight;
|
2012-01-29 17:53:12 +00:00
|
|
|
result.getWaterHeightInfo = _getWaterHeightInfo;
|
2012-01-24 13:16:20 +00:00
|
|
|
result.applyTextures = _applyTextures;
|
|
|
|
result.applyAtmosphere = _applyAtmosphere;
|
|
|
|
result.applyClouds = _applyClouds;
|
|
|
|
result.projectPoint = _projectPoint;
|
|
|
|
result.unprojectPoint = _unprojectPoint;
|
|
|
|
result.getPrecision = _getPrecision;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|