hrev52644 adds 1 changeset to branch 'master'
old head: 2e7e161dfb15eb6c992ead784e11c03f7b700a06
new head: e5aeaa8d037647fba21f728856f35a9d7548401b
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=e5aeaa8d0376+%5E2e7e161dfb15
----------------------------------------------------------------------------
e5aeaa8d0376: Mandelbrot: Implement subsampling
* Added subsampling. This makes the render look less noisy and generally
nicer.
Change-Id: I1dd667c8799bd97fb84e1401976da12ecf74ea8c
Reviewed-on: https://review.haiku-os.org/732
Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>
[ kerwizzy <kerwizzy@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev52644
Commit: e5aeaa8d037647fba21f728856f35a9d7548401b
URL: https://git.haiku-os.org/haiku/commit/?id=e5aeaa8d0376
Author: kerwizzy <kerwizzy@xxxxxxxxx>
Date: Sun Nov 25 13:47:54 2018 UTC
Committer: waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Wed Dec 12 22:17:24 2018 UTC
----------------------------------------------------------------------------
3 files changed, 67 insertions(+), 12 deletions(-)
src/apps/mandelbrot/FractalEngine.cpp | 44 +++++++++++++++++++++++--------
src/apps/mandelbrot/FractalEngine.h | 4 +++
src/apps/mandelbrot/Mandelbrot.cpp | 31 +++++++++++++++++++++-
----------------------------------------------------------------------------
diff --git a/src/apps/mandelbrot/FractalEngine.cpp
b/src/apps/mandelbrot/FractalEngine.cpp
index c20b2511df..f1d2bbc904 100644
--- a/src/apps/mandelbrot/FractalEngine.cpp
+++ b/src/apps/mandelbrot/FractalEngine.cpp
@@ -91,6 +91,9 @@ void FractalEngine::MessageReceived(BMessage* msg)
case MSG_SET_ITERATIONS:
fIterations = msg->GetUInt16("iterations", 0);
break;
+ case MSG_SET_SUBSAMPLING:
+ fSubsampling = msg->GetUInt8("subsampling", 1);
+ break;
case MSG_RESIZE: {
TRACE("Got MSG_RESIZE threads rendering\n");
@@ -251,19 +254,38 @@ void FractalEngine::RenderPixel(uint32 x, uint32 y)
double real = (x * fSize + fLocationX) - (fWidth / 2 * fSize);
double imaginary = (y * -(fSize) + fLocationY) - (fHeight / 2 *
-(fSize));
- int32 iterToEscape = (this->*fDoSet)(real, imaginary);
- uint16 loc = 0;
- if (iterToEscape == -1)
- // Didn't escape.
- loc = 999;
- else
- loc = 998 - (iterToEscape % 999);
+ double subsampleDelta = fSize / fSubsampling;
+ uint16 nSamples = fSubsampling * fSubsampling;
+
+ int16 totalR = 0;
+ int16 totalG = 0;
+ int16 totalB = 0;
+ for (uint8 subX = 0; subX < fSubsampling; subX++) {
+ for (uint8 subY = 0; subY < fSubsampling; subY++) {
+ double sampleReal = real + subX * subsampleDelta;
+ double sampleImaginary = imaginary + subY *
subsampleDelta;
+
+ int32 sampleIterToEscape = (this->*fDoSet)(sampleReal,
sampleImaginary);
+
+ uint16 sampleLoc = 0;
+ if (sampleIterToEscape == -1)
+ // Didn't escape.
+ sampleLoc = 999;
+ else
+ sampleLoc = 998 - (sampleIterToEscape % 999);
+ sampleLoc *= 3;
+
+ totalR += fColorset[sampleLoc + 0];
+ totalG += fColorset[sampleLoc + 1];
+ totalB += fColorset[sampleLoc + 2];
+ }
+ }
+
uint32 offsetBase = fWidth * y * 3 + x * 3;
- loc *= 3;
- fRenderBuffer[offsetBase + 2] = fColorset[loc + 0]; // fRenderBuffer is
BGR
- fRenderBuffer[offsetBase + 1] = fColorset[loc + 1];
- fRenderBuffer[offsetBase + 0] = fColorset[loc + 2];
+ fRenderBuffer[offsetBase + 2] = totalR / nSamples; // fRenderBuffer is
BGR
+ fRenderBuffer[offsetBase + 1] = totalG / nSamples;
+ fRenderBuffer[offsetBase + 0] = totalB / nSamples;
}
diff --git a/src/apps/mandelbrot/FractalEngine.h
b/src/apps/mandelbrot/FractalEngine.h
index 8411a1d3fa..9918071055 100644
--- a/src/apps/mandelbrot/FractalEngine.h
+++ b/src/apps/mandelbrot/FractalEngine.h
@@ -25,6 +25,7 @@ public:
MSG_CHANGE_SET = 'Frct',
MSG_SET_PALETTE,
MSG_SET_ITERATIONS,
+ MSG_SET_SUBSAMPLING,
MSG_RESIZE,
MSG_BUFFER_CREATED,
MSG_RENDER,
@@ -45,6 +46,9 @@ private:
uint8* fRenderBuffer;
uint32 fRenderBufferLen;
+ uint8 fSubsampling = 2;
+ // 1 disables subsampling.
+
BMessenger fMessenger;
uint8 fThreadCount;
diff --git a/src/apps/mandelbrot/Mandelbrot.cpp
b/src/apps/mandelbrot/Mandelbrot.cpp
index 7735d7901d..fe8a30cfc1 100644
--- a/src/apps/mandelbrot/Mandelbrot.cpp
+++ b/src/apps/mandelbrot/Mandelbrot.cpp
@@ -358,7 +358,12 @@ public:
MSG_ITER_4096,
MSG_ITER_8192,
MSG_ITER_12288,
- MSG_ITER_16384
+ MSG_ITER_16384,
+
+ MSG_SUBSAMPLING_1,
+ MSG_SUBSAMPLING_2,
+ MSG_SUBSAMPLING_3,
+ MSG_SUBSAMPLING_4
};
MandelbrotWindow(BRect frame);
~MandelbrotWindow() {}
@@ -381,6 +386,7 @@ MandelbrotWindow::MandelbrotWindow(BRect frame)
BMenu* setMenu;
BMenu* paletteMenu;
BMenu* iterMenu;
+ BMenu* subsamplingMenu;
BLayoutBuilder::Menu<>(menuBar)
.AddMenu(B_TRANSLATE("File"))
.AddItem(B_TRANSLATE("About"), B_ABOUT_REQUESTED)
@@ -417,6 +423,13 @@ MandelbrotWindow::MandelbrotWindow(BRect frame)
.AddItem("12288", MSG_ITER_12288)
.AddItem("16384", MSG_ITER_16384)
.End()
+ .AddMenu(B_TRANSLATE("Subsampling"))
+ .GetMenu(subsamplingMenu)
+ .AddItem(B_TRANSLATE("1 (none)"), MSG_SUBSAMPLING_1)
+ .AddItem("4", MSG_SUBSAMPLING_2)
+ .AddItem("9", MSG_SUBSAMPLING_3)
+ .AddItem("16", MSG_SUBSAMPLING_4)
+ .End()
.End();
setMenu->SetRadioMode(true);
setMenu->FindItem(MSG_MANDELBROT_SET)->SetMarked(true);
@@ -424,6 +437,8 @@ MandelbrotWindow::MandelbrotWindow(BRect frame)
paletteMenu->FindItem(MSG_ROYAL_PALETTE)->SetMarked(true);
iterMenu->SetRadioMode(true);
iterMenu->FindItem(MSG_ITER_1024)->SetMarked(true);
+ subsamplingMenu->SetRadioMode(true);
+ subsamplingMenu->FindItem(MSG_SUBSAMPLING_2)->SetMarked(true);
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
.SetInsets(0)
@@ -458,6 +473,14 @@ MandelbrotWindow::MandelbrotWindow(BRect frame)
fFractalView->RedrawFractal(); \
break; \
}
+#define HANDLE_SUBSAMPLING(uiwhat, id) \
+ case uiwhat: { \
+ BMessage msg(FractalEngine::MSG_SET_SUBSAMPLING); \
+ msg.AddUInt8("subsampling", id); \
+ fFractalView->fFractalEngine->PostMessage(&msg); \
+ fFractalView->RedrawFractal(); \
+ break; \
+ }
void
MandelbrotWindow::MessageReceived(BMessage* msg)
{
@@ -487,6 +510,11 @@ MandelbrotWindow::MessageReceived(BMessage* msg)
HANDLE_ITER(MSG_ITER_12288, 12288)
HANDLE_ITER(MSG_ITER_16384, 16384)
+ HANDLE_SUBSAMPLING(MSG_SUBSAMPLING_1, 1)
+ HANDLE_SUBSAMPLING(MSG_SUBSAMPLING_2, 2)
+ HANDLE_SUBSAMPLING(MSG_SUBSAMPLING_3, 3)
+ HANDLE_SUBSAMPLING(MSG_SUBSAMPLING_4, 4)
+
case B_ABOUT_REQUESTED: {
BAboutWindow* wind = new BAboutWindow("Mandelbrot",
"application/x-vnd.Haiku-Mandelbrot");
@@ -510,6 +538,7 @@ MandelbrotWindow::MessageReceived(BMessage* msg)
#undef HANDLE_SET
#undef HANDLE_PALETTE
#undef HANDLE_ITER
+#undef HANDLE_SUBSAMPLING
bool