2012-01-23 23:45:33 +00:00
|
|
|
#include "renderer.h"
|
2012-05-29 13:32:23 +00:00
|
|
|
|
2013-01-19 22:42:50 +00:00
|
|
|
#include "tools/lighting.h"
|
2013-10-26 21:19:49 +00:00
|
|
|
#include "System.h"
|
|
|
|
#include "Thread.h"
|
2012-01-29 21:45:58 +00:00
|
|
|
#include "render.h"
|
2013-10-29 20:28:59 +00:00
|
|
|
#include "Scenery.h"
|
2013-01-31 15:10:11 +00:00
|
|
|
#include "tools.h"
|
2013-11-12 20:34:35 +00:00
|
|
|
#include "camera.h"
|
|
|
|
#include "atmosphere/public.h"
|
|
|
|
#include "clouds/public.h"
|
|
|
|
#include "terrain/public.h"
|
|
|
|
#include "textures/public.h"
|
|
|
|
#include "water/public.h"
|
2012-01-23 23:45:33 +00:00
|
|
|
|
2013-11-11 14:42:11 +00:00
|
|
|
static RayCastingResult _RAYCASTING_NULL = {0, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
|
2012-01-24 13:16:20 +00:00
|
|
|
|
2012-01-29 21:45:58 +00:00
|
|
|
static void* _renderFirstPass(void* data)
|
|
|
|
{
|
|
|
|
Renderer* renderer = (Renderer*)data;
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2012-01-29 21:45:58 +00:00
|
|
|
sceneryRenderFirstPass(renderer);
|
|
|
|
renderer->is_rendering = 0;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-06-17 09:40:40 +00:00
|
|
|
static int _addRenderProgress(Renderer* renderer, double progress)
|
2012-01-29 21:45:58 +00:00
|
|
|
{
|
2013-01-31 15:10:11 +00:00
|
|
|
UNUSED(progress);
|
2012-01-30 13:10:16 +00:00
|
|
|
return !renderer->render_interrupt;
|
2012-01-29 21:45:58 +00:00
|
|
|
}
|
|
|
|
|
2013-01-31 15:10:11 +00:00
|
|
|
static Vector3 _getCameraLocation(Renderer* renderer, Vector3 target)
|
|
|
|
{
|
|
|
|
UNUSED(renderer);
|
|
|
|
UNUSED(target);
|
2013-04-27 19:41:57 +00:00
|
|
|
return cameraGetLocation(renderer->render_camera);
|
2013-01-31 15:10:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static Vector3 _getCameraDirection(Renderer* renderer, Vector3 target)
|
|
|
|
{
|
|
|
|
UNUSED(renderer);
|
|
|
|
UNUSED(target);
|
2013-04-27 19:41:57 +00:00
|
|
|
|
|
|
|
return cameraGetDirectionNormalized(renderer->render_camera);
|
2013-01-31 15:10:11 +00:00
|
|
|
}
|
|
|
|
|
2012-06-17 09:40:40 +00:00
|
|
|
static double _getPrecision(Renderer* renderer, Vector3 location)
|
2012-01-29 21:45:58 +00:00
|
|
|
{
|
2013-01-31 15:10:11 +00:00
|
|
|
UNUSED(renderer);
|
|
|
|
UNUSED(location);
|
2012-11-11 10:52:03 +00:00
|
|
|
return 0.0;
|
2012-01-29 21:45:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static Vector3 _projectPoint(Renderer* renderer, Vector3 point)
|
|
|
|
{
|
2013-05-28 12:56:50 +00:00
|
|
|
return cameraProject(renderer->render_camera, point);
|
2012-01-29 21:45:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static Vector3 _unprojectPoint(Renderer* renderer, Vector3 point)
|
|
|
|
{
|
2013-05-28 12:56:50 +00:00
|
|
|
return cameraUnproject(renderer->render_camera, point);
|
2012-01-29 21:45:58 +00:00
|
|
|
}
|
|
|
|
|
2012-06-17 09:40:40 +00:00
|
|
|
static void _pushTriangle(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, f_RenderFragmentCallback callback, void* callback_data)
|
2012-01-29 21:45:58 +00:00
|
|
|
{
|
|
|
|
Vector3 p1, p2, p3;
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2012-06-17 09:40:40 +00:00
|
|
|
p1 = renderer->projectPoint(renderer, v1);
|
|
|
|
p2 = renderer->projectPoint(renderer, v2);
|
|
|
|
p3 = renderer->projectPoint(renderer, v3);
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2012-06-17 09:40:40 +00:00
|
|
|
renderPushTriangle(renderer->render_area, p1, p2, p3, v1, v2, v3, callback, callback_data);
|
2012-01-29 21:45:58 +00:00
|
|
|
}
|
|
|
|
|
2012-06-17 09:40:40 +00:00
|
|
|
static void _pushQuad(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, f_RenderFragmentCallback callback, void* callback_data)
|
2012-01-29 21:45:58 +00:00
|
|
|
{
|
2012-06-17 09:40:40 +00:00
|
|
|
renderer->pushTriangle(renderer, v2, v3, v1, callback, callback_data);
|
|
|
|
renderer->pushTriangle(renderer, v4, v1, v3, callback, callback_data);
|
2012-01-29 21:45:58 +00:00
|
|
|
}
|
|
|
|
|
2013-04-06 13:29:12 +00:00
|
|
|
static void _pushDisplacedTriangle(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 ov1, Vector3 ov2, Vector3 ov3, f_RenderFragmentCallback callback, void* callback_data)
|
|
|
|
{
|
|
|
|
Vector3 p1, p2, p3;
|
|
|
|
|
|
|
|
p1 = renderer->projectPoint(renderer, v1);
|
|
|
|
p2 = renderer->projectPoint(renderer, v2);
|
|
|
|
p3 = renderer->projectPoint(renderer, v3);
|
|
|
|
|
|
|
|
renderPushTriangle(renderer->render_area, p1, p2, p3, ov1, ov2, ov3, callback, callback_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void _pushDisplacedQuad(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 ov1, Vector3 ov2, Vector3 ov3, Vector3 ov4, f_RenderFragmentCallback callback, void* callback_data)
|
|
|
|
{
|
|
|
|
renderer->pushDisplacedTriangle(renderer, v2, v3, v1, ov2, ov3, ov1, callback, callback_data);
|
|
|
|
renderer->pushDisplacedTriangle(renderer, v4, v1, v3, ov4, ov1, ov3, callback, callback_data);
|
|
|
|
}
|
|
|
|
|
2012-01-24 13:16:20 +00:00
|
|
|
static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds)
|
|
|
|
{
|
2013-09-27 20:04:05 +00:00
|
|
|
UNUSED(renderer);
|
|
|
|
UNUSED(location);
|
|
|
|
UNUSED(direction);
|
|
|
|
UNUSED(terrain);
|
|
|
|
UNUSED(water);
|
|
|
|
UNUSED(sky);
|
|
|
|
UNUSED(clouds);
|
2012-01-24 13:16:20 +00:00
|
|
|
return _RAYCASTING_NULL;
|
|
|
|
}
|
|
|
|
|
2013-02-03 21:18:32 +00:00
|
|
|
static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial* material)
|
2013-01-22 13:32:39 +00:00
|
|
|
{
|
2013-01-31 15:10:11 +00:00
|
|
|
LightStatus* light = lightingCreateStatus(renderer->lighting, location, renderer->getCameraLocation(renderer, location));
|
2013-01-22 13:32:39 +00:00
|
|
|
renderer->atmosphere->getLightingStatus(renderer, light, normal, 0);
|
|
|
|
Color result = lightingApplyStatus(light, normal, material);
|
|
|
|
lightingDeleteStatus(light);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2013-11-10 16:04:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Renderer::Renderer()
|
2013-02-03 21:18:32 +00:00
|
|
|
{
|
2013-11-10 16:04:38 +00:00
|
|
|
RenderParams params = {1, 1, 1, 5};
|
|
|
|
|
|
|
|
render_quality = 5;
|
|
|
|
render_width = 1;
|
|
|
|
render_height = 1;
|
|
|
|
render_interrupt = 0;
|
|
|
|
render_progress = 0.0;
|
|
|
|
is_rendering = 0;
|
|
|
|
render_camera = cameraCreateDefinition();
|
|
|
|
render_area = renderCreateArea(this);
|
|
|
|
|
|
|
|
renderSetParams(render_area, params);
|
|
|
|
|
|
|
|
addRenderProgress = _addRenderProgress;
|
|
|
|
getCameraLocation = _getCameraLocation;
|
|
|
|
getCameraDirection = _getCameraDirection;
|
|
|
|
getPrecision = _getPrecision;
|
|
|
|
projectPoint = _projectPoint;
|
|
|
|
unprojectPoint = _unprojectPoint;
|
|
|
|
pushTriangle = _pushTriangle;
|
|
|
|
pushQuad = _pushQuad;
|
|
|
|
pushDisplacedTriangle = _pushDisplacedTriangle;
|
|
|
|
pushDisplacedQuad = _pushDisplacedQuad;
|
|
|
|
|
|
|
|
rayWalking = _rayWalking;
|
|
|
|
|
|
|
|
applyLightingToSurface = _applyLightingToSurface;
|
|
|
|
|
|
|
|
lighting = lightingManagerCreate();
|
|
|
|
|
|
|
|
atmosphere = (AtmosphereRenderer*)AtmosphereRendererClass.create();
|
|
|
|
clouds = (CloudsRenderer*)CloudsRendererClass.create();
|
|
|
|
terrain = (TerrainRenderer*)TerrainRendererClass.create();
|
|
|
|
textures = (TexturesRenderer*)TexturesRendererClass.create();
|
|
|
|
water = (WaterRenderer*)WaterRendererClass.create();
|
2013-02-03 21:18:32 +00:00
|
|
|
}
|
|
|
|
|
2013-11-10 16:04:38 +00:00
|
|
|
Renderer::~Renderer()
|
2012-01-23 23:45:33 +00:00
|
|
|
{
|
2013-11-10 16:04:38 +00:00
|
|
|
cameraDeleteDefinition(render_camera);
|
|
|
|
lightingManagerDelete(lighting);
|
2012-01-23 23:45:33 +00:00
|
|
|
|
2013-11-10 16:04:38 +00:00
|
|
|
AtmosphereRendererClass.destroy(atmosphere);
|
|
|
|
CloudsRendererClass.destroy(clouds);
|
|
|
|
TerrainRendererClass.destroy(terrain);
|
|
|
|
TexturesRendererClass.destroy(textures);
|
|
|
|
WaterRendererClass.destroy(water);
|
2012-01-23 23:45:33 +00:00
|
|
|
|
2013-11-10 16:04:38 +00:00
|
|
|
renderDeleteArea(render_area);
|
2012-01-23 23:45:33 +00:00
|
|
|
}
|
2012-01-29 21:45:58 +00:00
|
|
|
|
2013-11-10 16:04:38 +00:00
|
|
|
Color Renderer::applyMediumTraversal(Vector3 location, Color color)
|
2012-01-29 21:45:58 +00:00
|
|
|
{
|
2013-11-10 16:04:38 +00:00
|
|
|
color = atmosphere->applyAerialPerspective(this, location, color).final;
|
|
|
|
color = clouds->getColor(this, color, getCameraLocation(this, location), location);
|
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-01-19 22:42:50 +00:00
|
|
|
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2013-01-20 15:07:45 +00:00
|
|
|
|
2013-11-10 16:04:38 +00:00
|
|
|
|
|
|
|
// Old API compat
|
|
|
|
|
|
|
|
Renderer* rendererCreate()
|
|
|
|
{
|
|
|
|
return new Renderer();
|
|
|
|
}
|
|
|
|
|
|
|
|
void rendererDelete(Renderer* renderer)
|
|
|
|
{
|
2013-11-02 15:43:43 +00:00
|
|
|
delete renderer;
|
2012-01-29 21:45:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void rendererSetPreviewCallbacks(Renderer* renderer, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update)
|
|
|
|
{
|
|
|
|
renderSetPreviewCallbacks(renderer->render_area, start, draw, update);
|
|
|
|
}
|
|
|
|
|
2012-06-13 15:38:11 +00:00
|
|
|
void rendererStart(Renderer* renderer, RenderParams params)
|
2012-01-29 21:45:58 +00:00
|
|
|
{
|
2013-11-03 12:00:31 +00:00
|
|
|
Thread thread(_renderFirstPass);
|
2012-01-29 21:45:58 +00:00
|
|
|
int loops;
|
2013-11-03 12:00:31 +00:00
|
|
|
int core_count = System::getCoreCount();
|
2012-01-29 21:45:58 +00:00
|
|
|
|
2012-06-13 15:38:11 +00:00
|
|
|
params.antialias = (params.antialias < 1) ? 1 : params.antialias;
|
|
|
|
params.antialias = (params.antialias > 4) ? 4 : params.antialias;
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2012-06-13 15:38:11 +00:00
|
|
|
renderer->render_quality = params.quality;
|
|
|
|
renderer->render_width = params.width * params.antialias;
|
|
|
|
renderer->render_height = params.height * params.antialias;
|
2012-01-29 21:45:58 +00:00
|
|
|
renderer->render_interrupt = 0;
|
|
|
|
renderer->render_progress = 0.0;
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2013-04-27 19:41:57 +00:00
|
|
|
cameraSetRenderSize(renderer->render_camera, renderer->render_width, renderer->render_height);
|
2012-01-29 21:45:58 +00:00
|
|
|
|
2013-11-13 19:07:35 +00:00
|
|
|
renderSetBackgroundColor(renderer->render_area, COLOR_BLACK);
|
2012-06-13 15:38:11 +00:00
|
|
|
renderSetParams(renderer->render_area, params);
|
2012-01-29 21:45:58 +00:00
|
|
|
renderClear(renderer->render_area);
|
|
|
|
|
2013-11-12 20:34:35 +00:00
|
|
|
renderer->prepare();
|
|
|
|
|
2012-01-29 21:45:58 +00:00
|
|
|
renderer->is_rendering = 1;
|
2013-11-03 12:00:31 +00:00
|
|
|
thread.start(renderer);
|
2012-01-29 21:45:58 +00:00
|
|
|
loops = 0;
|
|
|
|
|
|
|
|
while (renderer->is_rendering)
|
|
|
|
{
|
2013-11-03 12:00:31 +00:00
|
|
|
Thread::timeSleepMs(100);
|
2012-01-29 21:45:58 +00:00
|
|
|
|
|
|
|
if (++loops >= 10)
|
|
|
|
{
|
2013-04-27 19:41:57 +00:00
|
|
|
|
2012-01-29 21:45:58 +00:00
|
|
|
renderUpdate(renderer->render_area);
|
|
|
|
loops = 0;
|
|
|
|
}
|
|
|
|
}
|
2013-11-03 12:00:31 +00:00
|
|
|
thread.join();
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2012-01-29 21:45:58 +00:00
|
|
|
renderer->is_rendering = 1;
|
2013-06-11 10:03:50 +00:00
|
|
|
renderPostProcess(renderer->render_area, core_count);
|
2012-01-29 21:45:58 +00:00
|
|
|
renderer->is_rendering = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void rendererInterrupt(Renderer* renderer)
|
|
|
|
{
|
2012-01-30 13:10:16 +00:00
|
|
|
renderer->render_interrupt = 1;
|
2012-01-29 21:45:58 +00:00
|
|
|
}
|