diff --git a/TODO b/TODO index e0aaa6b..86db336 100644 --- a/TODO +++ b/TODO @@ -40,7 +40,8 @@ Technology Preview 2 : Technology Preview 3 : - Restore render progress. -- Add antialiasing option (pay attention to memory usage). +- Use bicubic interpolation for antialiasing. +- Improve large render/antialias memory consumption. - Add basic vegetation system ? - Texture shadowing and self-shadowing ? - Improve sky rendering (colors and light halo). diff --git a/gui_qt/dialogrender.cpp b/gui_qt/dialogrender.cpp index 6686de5..ee4c7f4 100644 --- a/gui_qt/dialogrender.cpp +++ b/gui_qt/dialogrender.cpp @@ -16,6 +16,7 @@ static void _renderStart(int width, int height, Color background) delete _current_dialog->pixbuf; _current_dialog->pixbuf = new QImage(width, height, QImage::Format_ARGB32); _current_dialog->pixbuf->fill(colorToQColor(background).rgb()); + _current_dialog->tellRenderSize(width, height); } static void _renderDraw(int x, int y, Color col) @@ -71,7 +72,7 @@ DialogRender::DialogRender(QWidget *parent, Renderer* renderer): _current_dialog = this; render_thread = NULL; _renderer = renderer; - + setModal(true); setWindowTitle(tr("Paysages 3D - Render")); setLayout(new QVBoxLayout()); @@ -89,6 +90,8 @@ DialogRender::DialogRender(QWidget *parent, Renderer* renderer): layout()->addWidget(progress); progress_value = 0; + connect(this, SIGNAL(renderSizeChanged(int, int)), this, SLOT(applyRenderSize(int, int))); + // TEMP progress->hide(); } @@ -105,9 +108,14 @@ DialogRender::~DialogRender() delete pixbuf; } +void DialogRender::tellRenderSize(int width, int height) +{ + emit renderSizeChanged(width, height); +} + void DialogRender::startRender(RenderParams params) { - applyRenderSize(params.width, params.height); + //applyRenderSize(params.width, params.height); rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate); render_thread = new RenderThread(_renderer, params); @@ -118,7 +126,7 @@ void DialogRender::startRender(RenderParams params) void DialogRender::loadLastRender() { - applyRenderSize(_renderer->render_width, _renderer->render_height); + //applyRenderSize(_renderer->render_width, _renderer->render_height); progress->hide(); rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate); diff --git a/gui_qt/dialogrender.h b/gui_qt/dialogrender.h index 2f2cf2b..4224aae 100644 --- a/gui_qt/dialogrender.h +++ b/gui_qt/dialogrender.h @@ -14,6 +14,7 @@ public: explicit DialogRender(QWidget *parent, Renderer* renderer); ~DialogRender(); + void tellRenderSize(int width, int height); void startRender(RenderParams params); void loadLastRender(); @@ -22,8 +23,11 @@ public: QProgressBar* progress; int progress_value; -public slots: +private slots: void applyRenderSize(int width, int height); + +signals: + void renderSizeChanged(int width, int height); private: QScrollArea* scroll; diff --git a/i18n/paysages_fr.ts b/i18n/paysages_fr.ts index 94229d5..52bb731 100644 --- a/i18n/paysages_fr.ts +++ b/i18n/paysages_fr.ts @@ -250,7 +250,7 @@ Maintenir Ctrl : Plus lent DialogRender - + Paysages 3D - Render Paysages 3D - Rendu diff --git a/lib_paysages/clouds.c b/lib_paysages/clouds.c index 213a0ee..aa9abb0 100644 --- a/lib_paysages/clouds.c +++ b/lib_paysages/clouds.c @@ -288,10 +288,12 @@ static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3 density /= coverage; if (density < layer->edge_length) { + density /= layer->edge_length; + val = 0.5 * noiseGet3DTotal(layer->edge_noise, position.x / layer->edge_scaling, position.y / layer->edge_scaling, position.z / layer->edge_scaling) / noiseGetMaxValue(layer->edge_noise); - val = (val - 0.5 + density / layer->edge_length) * layer->edge_scaling; + val = val - 0.5 + density; - return val; + return val * (density * coverage * layer->shape_scaling + (1.0 - density) * layer->edge_scaling); } else { diff --git a/lib_paysages/render.c b/lib_paysages/render.c index f4cc3e2..9fe0020 100644 --- a/lib_paysages/render.c +++ b/lib_paysages/render.c @@ -226,25 +226,50 @@ static inline void _setDirtyPixel(RenderArea* area, Array* pixel_data, int x, in area->dirty_count++; } -static void _processDirtyPixels(RenderArea* area) +static inline Color _getFinalPixel(RenderArea* area, int x, int y) { - Color col; + Color result, col; + int sx, sy; Array* pixel_data; - int x, y; - - for (y = area->dirty_down; y <= area->dirty_up; y++) + + result.r = result.g = result.b = 0.0; + result.a = 1.0; + for (sx = 0; sx < area->params.antialias; sx++) { - for (x = area->dirty_left; x <= area->dirty_right; x++) + for (sy = 0; sy < area->params.antialias; sy++) { - pixel_data = area->pixels + y * area->params.width * area->params.antialias + x; - if (pixel_data->dirty) + pixel_data = area->pixels + (y * area->params.antialias + sy) * area->params.width * area->params.antialias + (x * area->params.antialias + sx); + if (1 || pixel_data->dirty) { col = _getPixelColor(area->background_color, pixel_data); - area->callback_draw(x, y, col); + result.r += col.r / (double)(area->params.antialias * area->params.antialias); + result.g += col.g / (double)(area->params.antialias * area->params.antialias); + result.b += col.b / (double)(area->params.antialias * area->params.antialias); pixel_data->dirty = 0; } } } + + return result; +} + +static void _processDirtyPixels(RenderArea* area) +{ + int x, y; + int down, up, left, right; + + down = area->dirty_down / area->params.antialias; + up = area->dirty_up / area->params.antialias; + left = area->dirty_left / area->params.antialias; + right = area->dirty_right / area->params.antialias; + + for (y = down; y <= up; y++) + { + for (x = left; x <= right; x++) + { + area->callback_draw(x, y, _getFinalPixel(area, x, y)); + } + } area->callback_update(0.0); @@ -267,9 +292,9 @@ static void _setAllDirty(RenderArea* area) int x, y; area->dirty_left = 0; - area->dirty_right = area->params.width - 1; + area->dirty_right = area->params.width * area->params.antialias - 1; area->dirty_down = 0; - area->dirty_up = area->params.height - 1; + area->dirty_up = area->params.height * area->params.antialias - 1; for (y = area->dirty_down; y <= area->dirty_up; y++) { @@ -765,9 +790,7 @@ int renderSaveToFile(RenderArea* area, const char* path) { for (x = 0; x < area->params.width; x++) { - /* TODO Anti-alias */ - pixel_data = area->pixels + (y * area->params.width + x); - result = _getPixelColor(area->background_color, pixel_data); + result = _getFinalPixel(area, x, y); rgba = colorTo32BitRGBA(&result); data[y * area->params.width + x] = rgba; }