Added render tests from command line
This commit is contained in:
parent
035c957054
commit
4fcf1d071c
10 changed files with 173 additions and 73 deletions
|
@ -7,7 +7,9 @@ TARGET = paysages-cli
|
||||||
include(../../common.pri)
|
include(../../common.pri)
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp
|
main.cpp \
|
||||||
|
tests.cpp \
|
||||||
|
render.cpp
|
||||||
|
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../system/release/ -lpaysages_system
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../system/release/ -lpaysages_system
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../system/debug/ -lpaysages_system
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../system/debug/ -lpaysages_system
|
||||||
|
|
|
@ -1,60 +1,20 @@
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "CameraDefinition.h"
|
|
||||||
#include "AtmosphereDefinition.h"
|
|
||||||
#include "SoftwareCanvasRenderer.h"
|
#include "SoftwareCanvasRenderer.h"
|
||||||
#include "Scenery.h"
|
|
||||||
#include "RenderConfig.h"
|
#include "RenderConfig.h"
|
||||||
#include "ColorProfile.h"
|
#include "Scenery.h"
|
||||||
#include "Thread.h"
|
#include "AtmosphereDefinition.h"
|
||||||
|
#include "CameraDefinition.h"
|
||||||
|
|
||||||
class RenderThread: public Thread
|
#include <cstring>
|
||||||
{
|
|
||||||
public:
|
|
||||||
RenderThread(SoftwareCanvasRenderer *renderer, char *outputpath):
|
|
||||||
renderer(renderer), outputpath(outputpath)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void run() override
|
void startRender(SoftwareCanvasRenderer *renderer, const char *outputpath);
|
||||||
{
|
void runTestSuite();
|
||||||
renderer->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SoftwareCanvasRenderer *renderer;
|
|
||||||
char *outputpath;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void startRender(SoftwareCanvasRenderer *renderer, char *outputpath)
|
|
||||||
{
|
|
||||||
RenderThread thread(renderer, outputpath);
|
|
||||||
|
|
||||||
printf("\rRendering %s ... \n", outputpath);
|
|
||||||
thread.start();
|
|
||||||
|
|
||||||
while (thread.isWorking())
|
|
||||||
{
|
|
||||||
Thread::timeSleepMs(200);
|
|
||||||
|
|
||||||
printf("\rProgress : %0.1f%% ", renderer->getProgress() * 100.0);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
thread.join();
|
|
||||||
|
|
||||||
printf("\rSaving %s ... \n", outputpath);
|
|
||||||
remove(outputpath);
|
|
||||||
renderer->saveToDisk(outputpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void displayHelp()
|
static void displayHelp()
|
||||||
{
|
{
|
||||||
printf("Usage : paysages-cli [options]\n");
|
printf("Usage : paysages-cli [options]\n");
|
||||||
printf("Options :\n");
|
printf("Options :\n");
|
||||||
printf(" -h Show this help\n");
|
printf(" -h Show this help\n");
|
||||||
|
printf(" -ts Run the render test suite\n");
|
||||||
printf(" -f x Saved file to load (str)\n");
|
printf(" -f x Saved file to load (str)\n");
|
||||||
printf(" -n Number of pictures in the sequence\n");
|
printf(" -n Number of pictures in the sequence\n");
|
||||||
printf(" -rw x Render width (int)\n");
|
printf(" -rw x Render width (int)\n");
|
||||||
|
@ -93,6 +53,11 @@ int main(int argc, char** argv)
|
||||||
displayHelp();
|
displayHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(*argv, "-ts") == 0 || strcmp(*argv, "--testsuite") == 0)
|
||||||
|
{
|
||||||
|
runTestSuite();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (strcmp(*argv, "-f") == 0 || strcmp(*argv, "--file") == 0)
|
else if (strcmp(*argv, "-f") == 0 || strcmp(*argv, "--file") == 0)
|
||||||
{
|
{
|
||||||
if (argc--)
|
if (argc--)
|
||||||
|
|
42
src/interface/commandline/render.cpp
Normal file
42
src/interface/commandline/render.cpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "SoftwareCanvasRenderer.h"
|
||||||
|
|
||||||
|
class RenderThread: public Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RenderThread(SoftwareCanvasRenderer *renderer, const char *outputpath):
|
||||||
|
renderer(renderer), outputpath(outputpath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void run() override
|
||||||
|
{
|
||||||
|
renderer->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SoftwareCanvasRenderer *renderer;
|
||||||
|
const char *outputpath;
|
||||||
|
};
|
||||||
|
|
||||||
|
void startRender(SoftwareCanvasRenderer *renderer, const char *outputpath)
|
||||||
|
{
|
||||||
|
RenderThread thread(renderer, outputpath);
|
||||||
|
|
||||||
|
printf("\rRendering %s ... \n", outputpath);
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
while (thread.isWorking())
|
||||||
|
{
|
||||||
|
Thread::timeSleepMs(200);
|
||||||
|
|
||||||
|
printf("\rProgress : %0.1f%% ", renderer->getProgress() * 100.0);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
thread.join();
|
||||||
|
|
||||||
|
printf("\rSaving %s ... \n", outputpath);
|
||||||
|
remove(outputpath);
|
||||||
|
renderer->saveToDisk(outputpath);
|
||||||
|
}
|
||||||
|
|
71
src/interface/commandline/tests.cpp
Normal file
71
src/interface/commandline/tests.cpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#include "SoftwareCanvasRenderer.h"
|
||||||
|
#include "Scenery.h"
|
||||||
|
#include "CameraDefinition.h"
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
#include "AtmosphereDefinition.h"
|
||||||
|
#include "TexturesDefinition.h"
|
||||||
|
#include "TextureLayerDefinition.h"
|
||||||
|
#include "WaterDefinition.h"
|
||||||
|
#include "SurfaceMaterial.h"
|
||||||
|
#include "FloatNode.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
void startRender(SoftwareCanvasRenderer *renderer, const char *outputpath);
|
||||||
|
|
||||||
|
static void startTestRender(SoftwareCanvasRenderer *renderer, const std::string &name, int iteration)
|
||||||
|
{
|
||||||
|
std::ostringstream stream;
|
||||||
|
|
||||||
|
stream << "pic_test_" << name << "_";
|
||||||
|
stream.width(4);
|
||||||
|
stream.fill('0');
|
||||||
|
stream << iteration;
|
||||||
|
stream << ".png";
|
||||||
|
|
||||||
|
startRender(renderer, stream.str().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testGroundShadowQuality()
|
||||||
|
{
|
||||||
|
Scenery scenery;
|
||||||
|
srand(5);
|
||||||
|
scenery.getTerrain()->applyPreset(TerrainDefinition::TERRAIN_PRESET_STANDARD);
|
||||||
|
scenery.getTerrain()->propWaterHeight()->setValue(-0.5);
|
||||||
|
scenery.getWater()->propReflection()->setValue(0.0);
|
||||||
|
scenery.getWater()->material->base->r = 0.0;
|
||||||
|
scenery.getWater()->material->base->g = 0.3;
|
||||||
|
scenery.getWater()->material->base->b = 1.0;
|
||||||
|
scenery.getWater()->material->reflection = 0.0;
|
||||||
|
scenery.getWater()->foam_coverage = 0.0;
|
||||||
|
scenery.getWater()->transparency = 0.0;
|
||||||
|
scenery.getAtmosphere()->applyPreset(AtmosphereDefinition::ATMOSPHERE_PRESET_CLEAR_SUNSET);
|
||||||
|
scenery.getAtmosphere()->setDayTime(16, 45);
|
||||||
|
scenery.getTextures()->clear();
|
||||||
|
TextureLayerDefinition *texture = scenery.getTextures()->getTextureLayer(scenery.getTextures()->addLayer());
|
||||||
|
texture->displacement_height = 0.3;
|
||||||
|
texture->displacement_scaling = 2.0;
|
||||||
|
texture->displacement_offset = 0.0;
|
||||||
|
texture->material->setColor(0.6, 0.55, 0.57, 1.0);
|
||||||
|
texture->material->reflection = 0.006;
|
||||||
|
texture->material->shininess = 6.0;
|
||||||
|
texture->validate();
|
||||||
|
scenery.getCamera()->setLocation(Vector3(10.0, 10.0, -10.0));
|
||||||
|
scenery.getCamera()->setTarget(VECTOR_ZERO);
|
||||||
|
scenery.validate();
|
||||||
|
|
||||||
|
SoftwareCanvasRenderer renderer(&scenery);
|
||||||
|
renderer.setSize(400, 300);
|
||||||
|
for (int i = 1; i <= 10; i++)
|
||||||
|
{
|
||||||
|
// TODO keep same rasterization across renders, or keep rasterization quality low
|
||||||
|
renderer.render_quality = i;
|
||||||
|
startTestRender(&renderer, "ground_shadow_quality", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void runTestSuite()
|
||||||
|
{
|
||||||
|
testGroundShadowQuality();
|
||||||
|
}
|
||||||
|
|
|
@ -122,7 +122,11 @@ void MainModelerWindow::exit()
|
||||||
|
|
||||||
void MainModelerWindow::keyReleaseEvent(QKeyEvent *event)
|
void MainModelerWindow::keyReleaseEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
if (getState() == "Render Dialog")
|
if (event->modifiers() & Qt::ControlModifier && event->key() == Qt::Key_Q)
|
||||||
|
{
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
else if (getState() == "Render Dialog")
|
||||||
{
|
{
|
||||||
if (event->key() == Qt::Key_Escape)
|
if (event->key() == Qt::Key_Escape)
|
||||||
{
|
{
|
||||||
|
@ -153,13 +157,6 @@ void MainModelerWindow::keyReleaseEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
Logs::warning() << "Current scenery dump:" << std::endl << scenery->toString() << std::endl;
|
Logs::warning() << "Current scenery dump:" << std::endl << scenery->toString() << std::endl;
|
||||||
}
|
}
|
||||||
else if (event->key() == Qt::Key_Q)
|
|
||||||
{
|
|
||||||
if (event->modifiers() & Qt::ControlModifier)
|
|
||||||
{
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_N)
|
else if (event->key() == Qt::Key_N)
|
||||||
{
|
{
|
||||||
if (event->modifiers() & Qt::ControlModifier)
|
if (event->modifiers() & Qt::ControlModifier)
|
||||||
|
|
|
@ -14,6 +14,19 @@ paysages::software::RenderProgress::~RenderProgress()
|
||||||
delete lock;
|
delete lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderProgress::reset()
|
||||||
|
{
|
||||||
|
lock->acquire();
|
||||||
|
|
||||||
|
global = 0.0;
|
||||||
|
while (not subs.empty())
|
||||||
|
{
|
||||||
|
subs.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
lock->release();
|
||||||
|
}
|
||||||
|
|
||||||
void RenderProgress::add(int value)
|
void RenderProgress::add(int value)
|
||||||
{
|
{
|
||||||
lock->acquire();
|
lock->acquire();
|
||||||
|
|
|
@ -26,6 +26,7 @@ public:
|
||||||
|
|
||||||
inline double get() const {return global;}
|
inline double get() const {return global;}
|
||||||
|
|
||||||
|
void reset();
|
||||||
void add(int value=1);
|
void add(int value=1);
|
||||||
void enterSub(int count);
|
void enterSub(int count);
|
||||||
void exitSub();
|
void exitSub();
|
||||||
|
|
|
@ -69,6 +69,7 @@ void SoftwareCanvasRenderer::setSize(int width, int height, int samples)
|
||||||
void SoftwareCanvasRenderer::render()
|
void SoftwareCanvasRenderer::render()
|
||||||
{
|
{
|
||||||
started = true;
|
started = true;
|
||||||
|
progress->reset();
|
||||||
|
|
||||||
render_camera->setRenderSize(canvas->getWidth(), canvas->getHeight());
|
render_camera->setRenderSize(canvas->getWidth(), canvas->getHeight());
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,11 @@ void TerrainRayWalker::update()
|
||||||
ymin = info.min_height - disp;
|
ymin = info.min_height - disp;
|
||||||
ymax = info.max_height + disp;
|
ymax = info.max_height + disp;
|
||||||
|
|
||||||
ydispmax = disp * (0.5 + (double)renderer->render_quality * 0.1);
|
ydispmax = disp * (0.5 + (double)renderer->render_quality * 0.05);
|
||||||
ydispmin = -ydispmax;
|
ydispmin = -ydispmax;
|
||||||
|
|
||||||
minstep = 1.0 * terrain->scaling / (double)(renderer->render_quality * renderer->render_quality);
|
minstep = 0.5 * terrain->scaling / (double)renderer->render_quality;
|
||||||
maxstep = 10.0 * terrain->scaling / (double)renderer->render_quality;
|
maxstep = 50.0 * terrain->scaling / (double)renderer->render_quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Vector3 _getShiftAxis(const Vector3 &direction)
|
static inline Vector3 _getShiftAxis(const Vector3 &direction)
|
||||||
|
@ -63,7 +63,14 @@ bool TerrainRayWalker::startWalking(const Vector3 &start, Vector3 direction, dou
|
||||||
if (escape_angle != 0.0)
|
if (escape_angle != 0.0)
|
||||||
{
|
{
|
||||||
// Prepare escape
|
// Prepare escape
|
||||||
|
if (renderer->render_quality >= 7)
|
||||||
|
{
|
||||||
shift_step = escape_angle / (double)(renderer->render_quality * renderer->render_quality);
|
shift_step = escape_angle / (double)(renderer->render_quality * renderer->render_quality);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shift_step = escape_angle / (double)renderer->render_quality;
|
||||||
|
}
|
||||||
shift_matrix = Matrix4::newRotateAxis(-shift_step, _getShiftAxis(direction));
|
shift_matrix = Matrix4::newRotateAxis(-shift_step, _getShiftAxis(direction));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +128,7 @@ bool TerrainRayWalker::startWalking(const Vector3 &start, Vector3 direction, dou
|
||||||
previous_cursor = cursor;
|
previous_cursor = cursor;
|
||||||
walked_length += step_length;
|
walked_length += step_length;
|
||||||
|
|
||||||
step_length = diff * 3.0 / (double)renderer->render_quality;
|
step_length = diff * 10.0 / (double)renderer->render_quality;
|
||||||
if (step_length < minstep)
|
if (step_length < minstep)
|
||||||
{
|
{
|
||||||
step_length = minstep;
|
step_length = minstep;
|
||||||
|
|
|
@ -175,6 +175,7 @@ bool TerrainRenderer::applyLightFilter(LightComponent &light, const Vector3 &at)
|
||||||
|
|
||||||
// Walk to find an intersection
|
// Walk to find an intersection
|
||||||
double escape_angle = definition->shadow_smoothing;
|
double escape_angle = definition->shadow_smoothing;
|
||||||
|
// TODO max length should depend on the sun light angle and altitude range
|
||||||
if (walker->startWalking(at, direction_to_light, escape_angle, 100.0, walk_result))
|
if (walker->startWalking(at, direction_to_light, escape_angle, 100.0, walk_result))
|
||||||
{
|
{
|
||||||
if (walk_result.escape_angle == 0.0)
|
if (walk_result.escape_angle == 0.0)
|
||||||
|
|
Loading…
Reference in a new issue