From 13904be001bee51a00deca29900568896bd98fd5 Mon Sep 17 00:00:00 2001 From: Michael Lemaire Date: Wed, 20 Aug 2014 16:45:45 +0200 Subject: [PATCH] Optimization: replaced some divisions by inverse multiplications --- Makefile | 8 ++++---- src/basics/NoiseGenerator.cpp | 20 ++++++++++---------- src/basics/NoiseGenerator.h | 2 +- src/definition/CameraDefinition.cpp | 5 ++++- src/definition/CameraDefinition.h | 2 ++ src/interface/commandline/main.cpp | 11 ++++++----- src/interface/desktop/dialognoise.cpp | 6 +++--- src/render/software/CanvasPreview.cpp | 18 +++++++++--------- src/render/software/Rasterizer.cpp | 12 ++++++------ src/render/software/TexturesRenderer.cpp | 8 ++++---- 10 files changed, 49 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index 56d7343..f3cb8b7 100644 --- a/Makefile +++ b/Makefile @@ -43,17 +43,17 @@ else endif run_cli:build - LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/commandline/paysages-cli + LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/commandline/paysages-cli $(ARGS) run:build - LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/desktop/paysages-gui + LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/desktop/paysages-gui $(ARGS) profile:build - LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g fp ${BUILDPATH}/interface/desktop/paysages-gui $(ARGS) + LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g ${BUILDPATH}/interface/desktop/paysages-gui $(ARGS) perf report -g profile_cli:build - LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g fp ${BUILDPATH}/interface/commandline/paysages-cli $(ARGS) + LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g ${BUILDPATH}/interface/commandline/paysages-cli $(ARGS) perf report -g package:build diff --git a/src/basics/NoiseGenerator.cpp b/src/basics/NoiseGenerator.cpp index 06b3f85..907095b 100644 --- a/src/basics/NoiseGenerator.cpp +++ b/src/basics/NoiseGenerator.cpp @@ -45,7 +45,7 @@ void NoiseGenerator::save(PackStream* stream) { NoiseLevel* level = levels + x; - stream->write(&level->wavelength); + stream->write(&level->frequency); stream->write(&level->amplitude); stream->write(&level->minvalue); } @@ -69,7 +69,7 @@ void NoiseGenerator::load(PackStream* stream) { NoiseLevel* level = levels + x; - stream->read(&level->wavelength); + stream->read(&level->frequency); stream->read(&level->amplitude); stream->read(&level->minvalue); } @@ -215,7 +215,7 @@ void NoiseGenerator::addLevelSimple(double scaling, double minvalue, double maxv { NoiseLevel level; - level.wavelength = scaling; + level.frequency = 1.0 / scaling; level.minvalue = minvalue; level.amplitude = maxvalue - minvalue; @@ -230,7 +230,7 @@ void NoiseGenerator::addLevels(int level_count, NoiseLevel start_level, double s { addLevel(start_level); start_level.minvalue += start_level.amplitude * (1.0 - amplitude_factor) * center_factor; - start_level.wavelength *= scaling_factor; + start_level.frequency /= scaling_factor; start_level.amplitude *= amplitude_factor; } } @@ -239,7 +239,7 @@ void NoiseGenerator::addLevelsSimple(int level_count, double scaling, double min { NoiseLevel level; - level.wavelength = scaling; + level.frequency = 1.0 / scaling; level.minvalue = minvalue; level.amplitude = maxvalue - minvalue; addLevels(level_count, level, 0.5, 0.5, center_factor); @@ -284,7 +284,7 @@ void NoiseGenerator::setLevelSimple(int index, double scaling, double minvalue, { NoiseLevel level; - level.wavelength = scaling; + level.frequency = 1.0 / scaling; level.minvalue = minvalue; level.amplitude = maxvalue - minvalue; @@ -313,7 +313,7 @@ void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int ad levels[level].amplitude *= factor; if (adjust_scaling) { - levels[level].wavelength *= factor; + levels[level].frequency /= factor; } } height_offset = minvalue + (height_offset - current_minvalue) * factor; @@ -371,7 +371,7 @@ static inline double _fixValue(double value, double ridge, double curve) inline double NoiseGenerator::_get1DLevelValue(NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x) { - return level->minvalue + _fixValue(_func_noise_1d(x / level->wavelength + offset.x), function.ridge_factor, function.curve_factor) * level->amplitude; + return level->minvalue + _fixValue(_func_noise_1d(x * level->frequency + offset.x), function.ridge_factor, function.curve_factor) * level->amplitude; } double NoiseGenerator::get1DLevel(int level, double x) @@ -428,7 +428,7 @@ double NoiseGenerator::get1DDetail(double x, double detail) inline double NoiseGenerator::_get2DLevelValue(NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y) { - return level->minvalue + _fixValue(_func_noise_2d(x / level->wavelength + offset.x, y / level->wavelength + offset.y), function.ridge_factor, function.curve_factor) * level->amplitude; + return level->minvalue + _fixValue(_func_noise_2d(x * level->frequency + offset.x, y * level->frequency + offset.y), function.ridge_factor, function.curve_factor) * level->amplitude; } double NoiseGenerator::get2DLevel(int level, double x, double y) @@ -485,7 +485,7 @@ double NoiseGenerator::get2DDetail(double x, double y, double detail) inline double NoiseGenerator::_get3DLevelValue(NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y, double z) { - return level->minvalue + _fixValue(_func_noise_3d(x / level->wavelength + offset.x, y / level->wavelength + offset.y, z / level->wavelength + offset.z), function.ridge_factor, function.curve_factor) * level->amplitude; + return level->minvalue + _fixValue(_func_noise_3d(x * level->frequency + offset.x, y * level->frequency + offset.y, z * level->frequency + offset.z), function.ridge_factor, function.curve_factor) * level->amplitude; } double NoiseGenerator::get3DLevel(int level, double x, double y, double z) diff --git a/src/basics/NoiseGenerator.h b/src/basics/NoiseGenerator.h index 89eb688..ca94f6f 100644 --- a/src/basics/NoiseGenerator.h +++ b/src/basics/NoiseGenerator.h @@ -28,7 +28,7 @@ public: typedef struct { - double wavelength; + double frequency; double amplitude; double minvalue; } NoiseLevel; diff --git a/src/definition/CameraDefinition.cpp b/src/definition/CameraDefinition.cpp index 5fcfce6..1f43199 100644 --- a/src/definition/CameraDefinition.cpp +++ b/src/definition/CameraDefinition.cpp @@ -90,11 +90,14 @@ void CameraDefinition::validate() projector = mperspective.mult(Matrix4::newLookAt(location, target, up)); unprojector = projector.inversed(); + + inv_x_factor = 1.0 / (0.5 * width); + inv_y_factor = 1.0 / (0.5 * height); } double CameraDefinition::getRealDepth(const Vector3 &projected) const { - Vector3 v(projected.x / (0.5 * width) - 1.0, -(projected.y / (0.5 * height) - 1.0), projected.z); + Vector3 v(projected.x * inv_x_factor - 1.0, -(projected.y * inv_x_factor - 1.0), projected.z); return unperspective.transform(v).z; } diff --git a/src/definition/CameraDefinition.h b/src/definition/CameraDefinition.h index faab350..3268381 100644 --- a/src/definition/CameraDefinition.h +++ b/src/definition/CameraDefinition.h @@ -85,6 +85,8 @@ private: Matrix4 projector; Matrix4 unprojector; Matrix4 unperspective; + double inv_x_factor; + double inv_y_factor; }; } diff --git a/src/interface/commandline/main.cpp b/src/interface/commandline/main.cpp index 447ce61..665d7ef 100644 --- a/src/interface/commandline/main.cpp +++ b/src/interface/commandline/main.cpp @@ -9,13 +9,13 @@ #include "Scenery.h" #include "RenderConfig.h" -void startRender(SoftwareRenderer *renderer, char *outputpath, const RenderConfig ¶ms) +void startRender(SoftwareCanvasRenderer *renderer, char *outputpath) { - /*printf("\rRendering %s ... \n", outputpath); - renderer->start(params); + printf("\rRendering %s ... \n", outputpath); + renderer->render(); printf("\rSaving %s ... \n", outputpath); remove(outputpath); - renderer->render_area->saveToFile(outputpath);*/ + //renderer->render_area->saveToFile(outputpath); } void displayHelp() @@ -179,12 +179,13 @@ int main(int argc, char** argv) camera->setLocation(camera->getLocation().add(step)); renderer = new SoftwareCanvasRenderer(); + renderer->setConfig(conf_render_params); renderer->setScenery(scenery); if (outputcount >= conf_first_picture) { sprintf(outputpath, "output/pic%05d.png", outputcount); - startRender(renderer, outputpath, conf_render_params); + startRender(renderer, outputpath); } delete renderer; diff --git a/src/interface/desktop/dialognoise.cpp b/src/interface/desktop/dialognoise.cpp index b63f52e..57a826e 100644 --- a/src/interface/desktop/dialognoise.cpp +++ b/src/interface/desktop/dialognoise.cpp @@ -282,7 +282,7 @@ void DialogNoise::addLevel() NoiseGenerator::NoiseLevel level; level.amplitude = 0.1; - level.wavelength = 0.1; + level.frequency = 0.1; _current->addLevel(level); @@ -330,7 +330,7 @@ void DialogNoise::levelChanged(int row) ((PreviewLevel*)previewLevel)->setLevel(row); slider_height->setValue(_current_level_params.amplitude * 1000.0); - slider_scaling->setValue(_current_level_params.wavelength * 1000.0); + slider_scaling->setValue(_current_level_params.frequency * 1000.0); } // TODO else ... } @@ -345,7 +345,7 @@ void DialogNoise::heightChanged(int value) void DialogNoise::scalingChanged(int value) { - _current_level_params.wavelength = ((double)value) / 1000.0; + _current_level_params.frequency = ((double)value) / 1000.0; _current->setLevel(_current_level, _current_level_params); previewLevel->redraw(); previewTotal->redraw(); diff --git a/src/render/software/CanvasPreview.cpp b/src/render/software/CanvasPreview.cpp index 0a31e26..6e49eec 100644 --- a/src/render/software/CanvasPreview.cpp +++ b/src/render/software/CanvasPreview.cpp @@ -63,8 +63,8 @@ void CanvasPreview::setSize(int real_width, int real_height, int preview_width, dirty_up = -1; scaled = (real_width != preview_height or real_height != preview_height); - factor_x = (double)real_width / (double)preview_width; - factor_y = (double)real_height / (double)preview_height; + factor_x = (double)preview_width / (double)real_width; + factor_y = (double)preview_height / (double)real_height; factor = factor_x * factor_y; lock->release(); @@ -125,12 +125,10 @@ void CanvasPreview::pushPixel(int real_x, int real_y, const Color &old_color, co { int x, y; - lock->acquire(); - if (scaled) { - x = int(real_x / factor_x); - y = int(real_y / factor_y); + x = int(real_x * factor_x); + y = int(real_y * factor_y); x = (x >= width) ? width - 1 : x; y = (y >= height) ? height - 1 : y; @@ -143,10 +141,12 @@ void CanvasPreview::pushPixel(int real_x, int real_y, const Color &old_color, co CHECK_COORDINATES(x, y); + lock->acquire(); + Color* pixel = pixels + (y * width + x); - pixel->r = pixel->r - old_color.r / factor + new_color.r / factor; - pixel->g = pixel->g - old_color.g / factor + new_color.g / factor; - pixel->b = pixel->b - old_color.b / factor + new_color.b / factor; + pixel->r = pixel->r - old_color.r * factor + new_color.r * factor; + pixel->g = pixel->g - old_color.g * factor + new_color.g * factor; + pixel->b = pixel->b - old_color.b * factor + new_color.b * factor; // Set pixel dirty if (x < dirty_left) diff --git a/src/render/software/Rasterizer.cpp b/src/render/software/Rasterizer.cpp index c75fe08..ed8ff8f 100644 --- a/src/render/software/Rasterizer.cpp +++ b/src/render/software/Rasterizer.cpp @@ -174,16 +174,16 @@ void Rasterizer::scanInterpolate(CameraDefinition* camera, ScanPoint* v1, ScanPo { Vector3 vec1(v1->pixel.x, v1->pixel.y, v1->pixel.z); Vector3 vecdiff(diff->pixel.x, diff->pixel.y, diff->pixel.z); - double v1depth = camera->getRealDepth(vec1); - double v2depth = camera->getRealDepth(vec1.add(vecdiff)); - double factor = ((1.0 - value) / v1depth + value / v2depth); + double v1depth = 1.0 / camera->getRealDepth(vec1); + double v2depth = 1.0 / camera->getRealDepth(vec1.add(vecdiff)); + double factor = 1.0 / ((1.0 - value) * v1depth + value * v2depth); result->pixel.x = v1->pixel.x + diff->pixel.x * value; result->pixel.y = v1->pixel.y + diff->pixel.y * value; result->pixel.z = v1->pixel.z + diff->pixel.z * value; - result->location.x = ((1.0 - value) * (v1->location.x / v1depth) + value * (v1->location.x + diff->location.x) / v2depth) / factor; - result->location.y = ((1.0 - value) * (v1->location.y / v1depth) + value * (v1->location.y + diff->location.y) / v2depth) / factor; - result->location.z = ((1.0 - value) * (v1->location.z / v1depth) + value * (v1->location.z + diff->location.z) / v2depth) / factor; + result->location.x = ((1.0 - value) * (v1->location.x * v1depth) + value * (v1->location.x + diff->location.x) * v2depth) * factor; + result->location.y = ((1.0 - value) * (v1->location.y * v1depth) + value * (v1->location.y + diff->location.y) * v2depth) * factor; + result->location.z = ((1.0 - value) * (v1->location.z * v1depth) + value * (v1->location.z + diff->location.z) * v2depth) * factor; result->client = v1->client; } diff --git a/src/render/software/TexturesRenderer.cpp b/src/render/software/TexturesRenderer.cpp index 056881a..6dce8e0 100644 --- a/src/render/software/TexturesRenderer.cpp +++ b/src/render/software/TexturesRenderer.cpp @@ -40,10 +40,10 @@ double TexturesRenderer::getTriplanarNoise(NoiseGenerator *noise, const Vector3 double mXY = fabs(normal.z); double mXZ = fabs(normal.y); double mYZ = fabs(normal.x); - double total = mXY + mXZ + mYZ; - mXY /= total; - mXZ /= total; - mYZ /= total; + double total = 1.0 / (mXY + mXZ + mYZ); + mXY *= total; + mXZ *= total; + mYZ *= total; return noiseXY * mXY + noiseXZ * mXZ + noiseYZ * mYZ; }