From 6b2b6ede7f5a8c11d657aac1c0194fb854b68d28 Mon Sep 17 00:00:00 2001 From: mfeemster Date: Mon, 27 Oct 2014 14:21:06 -0700 Subject: [PATCH] Fix bug when using rotation with strips by adding a new member to Ember named m_RotCenterY which is a copy of the original center value since the center value gets changed when using strips. Change PaletteList Count() member to Size() to be consistent with other code. Remove PaletteImage option, it's unused. Improve documentation for some other options. Make ComposePath() always return a unique string. Add Random Palette and Random Adjustment buttons. Another attempt at solving the locale bug with the affine adjustment combo boxes. --- Source/Ember/Ember.h | 8 +- Source/Ember/Isaac.h | 5 +- Source/Ember/PaletteList.h | 6 +- Source/Ember/Renderer.cpp | 5 +- Source/Ember/XmlToEmber.h | 2 +- Source/EmberCL/RendererCL.cpp | 2 +- Source/EmberCL/RendererCL.h | 5 +- Source/EmberCommon/EmberCommon.h | 1 - Source/EmberCommon/EmberOptions.h | 20 +- Source/EmberTester/EmberTester.cpp | 2 +- .../Fractorium/FinalRenderEmberController.cpp | 14 +- Source/Fractorium/Fractorium.h | 2 + Source/Fractorium/Fractorium.ui | 665 +++++++++--------- Source/Fractorium/FractoriumPalette.cpp | 53 +- Source/Fractorium/FractoriumParams.cpp | 6 +- Source/Fractorium/FractoriumXformsAffine.cpp | 12 + Source/Fractorium/FractoriumXformsColor.cpp | 4 +- Source/Fractorium/FractoriumXformsXaos.cpp | 1 + Source/Fractorium/GLWidget.cpp | 2 +- 19 files changed, 440 insertions(+), 375 deletions(-) diff --git a/Source/Ember/Ember.h b/Source/Ember/Ember.h index 0bbd8f2..7742c1d 100644 --- a/Source/Ember/Ember.h +++ b/Source/Ember/Ember.h @@ -108,6 +108,7 @@ public: m_CamMat = ember.m_CamMat; m_CenterX = T(ember.m_CenterX); m_CenterY = T(ember.m_CenterY); + m_RotCenterY = T(ember.m_RotCenterY); m_Rotate = T(ember.m_Rotate); m_Hue = T(ember.m_Hue); m_Brightness = T(ember.m_Brightness); @@ -201,6 +202,7 @@ public: m_CamMat = m3T(0); m_CenterX = 0; m_CenterY = 0; + m_RotCenterY = 0; m_Rotate = 0; m_Hue = 0; m_Brightness = 4; @@ -761,6 +763,7 @@ public: InterpI<&Ember::m_Supersample>(embers, coefs, size); InterpT<&Ember::m_CenterX>(embers, coefs, size); InterpT<&Ember::m_CenterY>(embers, coefs, size); + InterpT<&Ember::m_RotCenterY>(embers, coefs, size); InterpX, &Ember::m_Background>(embers, coefs, size); m_Background.a = bgAlphaSave;//Don't interp alpha. InterpT<&Ember::m_PixelsPerUnit>(embers, coefs, size); InterpT<&Ember::m_SpatialFilterRadius>(embers, coefs, size); @@ -1269,6 +1272,7 @@ public: m_Palette.m_Index = -1; m_CenterX = 0; m_CenterY = 0; + m_RotCenterY = 0; m_Gamma = 4; m_Vibrancy = 1; m_Brightness = 4; @@ -1392,6 +1396,7 @@ public: << "Depth Blur: " << m_CamDepthBlur << endl << "CenterX: " << m_CenterX << endl << "CenterY: " << m_CenterY << endl + << "RotCenterY: " << m_RotCenterY << endl << "Rotate: " << m_Rotate << endl << "Hue: " << m_Hue << endl << "Brightness: " << m_Brightness << endl @@ -1523,10 +1528,11 @@ public: m3T m_CamMat; //The camera offset from the center of the cartesian plane. Since this is the camera offset, the final output image will be moved in the opposite - //direction of the values specified. + //direction of the values specified. There is also a second copy of the Y coordinate needed because m_CenterY will be modified during strips rendering. //Xml field: "center". T m_CenterX; T m_CenterY; + T m_RotCenterY; //Rotate the camera by this many degrees. Since this is a camera rotation, the final output image will be rotated counter-clockwise. //Xml field: "rotate". diff --git a/Source/Ember/Isaac.h b/Source/Ember/Isaac.h index f1ed2ff..56e8060 100644 --- a/Source/Ember/Isaac.h +++ b/Source/Ember/Isaac.h @@ -100,9 +100,10 @@ public: } /// - /// Return the next random integer between 0 and the value passed in. + /// Return the next random integer between 0 and the value passed in minus 1. /// - /// A value one greater than the maximum value that will be returned + /// A value one greater than the maximum value that will be returned + /// A value between 0 and the value passed in minus 1 inline T Rand(T upper) { return (upper == 0) ? Rand() : Rand() % upper; diff --git a/Source/Ember/PaletteList.h b/Source/Ember/PaletteList.h index 5052944..f17c320 100644 --- a/Source/Ember/PaletteList.h +++ b/Source/Ember/PaletteList.h @@ -80,7 +80,7 @@ public: if (!m_Palettes.empty()) { if (i == -1) - return &m_Palettes[QTIsaac::GlobalRand->Rand() % Count()]; + return &m_Palettes[QTIsaac::GlobalRand->Rand() % Size()]; else if (i < (int)m_Palettes.size()) return &m_Palettes[i]; } @@ -95,7 +95,7 @@ public: /// A pointer to the palette if found, else nullptr Palette* GetPaletteByName(const string&& name) { - for (unsigned int i = 0; i < Count(); i++) + for (unsigned int i = 0; i < Size(); i++) if (m_Palettes[i].m_Name == name) return &m_Palettes[i]; @@ -136,7 +136,7 @@ public: /// Accessors. /// bool Init() { return m_Init; } - unsigned int Count() { return (unsigned int)m_Palettes.size(); } + size_t Size() { return m_Palettes.size(); } private: /// diff --git a/Source/Ember/Renderer.cpp b/Source/Ember/Renderer.cpp index 361eca3..f0d7ae4 100644 --- a/Source/Ember/Renderer.cpp +++ b/Source/Ember/Renderer.cpp @@ -459,6 +459,7 @@ eRenderStatus Renderer::Run(vector& finalImage, doubl //it.Tic(); if (m_Embers.size() > 1) Interpolater::Interpolate(m_Embers, temporalTime, 0, m_Ember);//This will perform all necessary precalcs via the ember/xform/variation assignment operators. + //it.Toc("Interp 3"); if (!resume && !AssignIterator()) @@ -1478,10 +1479,10 @@ void Renderer::Accumulate(Point* samples, size_t sampleCount, con if (Rotate() != 0) { T p00 = samples[i].m_X - CenterX(); - T p11 = samples[i].m_Y - CenterY(); + T p11 = samples[i].m_Y - m_Ember.m_RotCenterY; samples[i].m_X = (p00 * m_RotMat.A()) + (p11 * m_RotMat.B()) + CenterX(); - samples[i].m_Y = (p00 * m_RotMat.D()) + (p11 * m_RotMat.E()) + CenterY(); + samples[i].m_Y = (p00 * m_RotMat.D()) + (p11 * m_RotMat.E()) + m_Ember.m_RotCenterY; } //Checking this first before converting gives better performance than converting and checking a single value, which the original did. diff --git a/Source/Ember/XmlToEmber.h b/Source/Ember/XmlToEmber.h index b4542b2..76770e2 100644 --- a/Source/Ember/XmlToEmber.h +++ b/Source/Ember/XmlToEmber.h @@ -655,7 +655,7 @@ private: } currentEmber.m_CenterX = T(vals[0]); - currentEmber.m_CenterY = T(vals[1]); + currentEmber.m_CenterY = currentEmber.m_RotCenterY = T(vals[1]); } else if (!Compare(curAtt->name, "filter_shape")) { diff --git a/Source/EmberCL/RendererCL.cpp b/Source/EmberCL/RendererCL.cpp index bc7a889..0fab12d 100644 --- a/Source/EmberCL/RendererCL.cpp +++ b/Source/EmberCL/RendererCL.cpp @@ -1297,7 +1297,7 @@ EmberCL RendererCL::ConvertEmber(Ember& ember) emberCL.m_RotE = m_RotMat.E(); emberCL.m_CamMat = ember.m_CamMat; emberCL.m_CenterX = CenterX(); - emberCL.m_CenterY = CenterY(); + emberCL.m_CenterY = ember.m_RotCenterY; emberCL.m_CamZPos = ember.m_CamZPos; emberCL.m_CamPerspective = ember.m_CamPerspective; emberCL.m_CamYaw = ember.m_CamYaw; diff --git a/Source/EmberCL/RendererCL.h b/Source/EmberCL/RendererCL.h index 927d142..2829765 100644 --- a/Source/EmberCL/RendererCL.h +++ b/Source/EmberCL/RendererCL.h @@ -7,11 +7,14 @@ #include "FinalAccumOpenCLKernelCreator.h" /// -/// RendererCL class. +/// RendererCLBase and RendererCL classes. /// namespace EmberCLns { +/// +/// Serves only as an interface for OpenCL specific rendering functions. +/// class EMBERCL_API RendererCLBase { public: diff --git a/Source/EmberCommon/EmberCommon.h b/Source/EmberCommon/EmberCommon.h index 97fc416..b6788ab 100644 --- a/Source/EmberCommon/EmberCommon.h +++ b/Source/EmberCommon/EmberCommon.h @@ -313,7 +313,6 @@ static bool StripsRender(RendererBase* renderer, Ember& ember, vector 1) diff --git a/Source/EmberCommon/EmberOptions.h b/Source/EmberCommon/EmberOptions.h index 33a2b60..b06bb98 100644 --- a/Source/EmberCommon/EmberOptions.h +++ b/Source/EmberCommon/EmberOptions.h @@ -99,7 +99,7 @@ enum eOptionIDs OPT_SUFFIX, OPT_FORMAT, OPT_PALETTE_FILE, - OPT_PALETTE_IMAGE, + //OPT_PALETTE_IMAGE, OPT_ID, OPT_URL, OPT_NICK, @@ -292,7 +292,7 @@ public: INITBOOLOPTION(Enclosed, Eob(OPT_USE_GENOME, OPT_ENCLOSED, _T("--enclosed"), true, SO_NONE, "\t--enclosed Use enclosing XML tags [default: false].\n")); INITBOOLOPTION(NoEdits, Eob(OPT_USE_GENOME, OPT_NO_EDITS, _T("--noedits"), false, SO_NONE, "\t--noedits Exclude edit tags when writing Xml [default: false].\n")); INITBOOLOPTION(UnsmoothEdge, Eob(OPT_USE_GENOME, OPT_UNSMOOTH_EDGE, _T("--unsmoother"), false, SO_NONE, "\t--unsmoother Do not use smooth blending for sheep edges [default: false].\n")); - INITBOOLOPTION(LockAccum, Eob(OPT_USE_ALL, OPT_LOCK_ACCUM, _T("--lock_accum"), false, SO_NONE, "\t--lock_accum Lock threads when accumulating to the histogram using the CPU (ignored for OpenCL). This will drop performance to that of single threading [default: false].\n")); + INITBOOLOPTION(LockAccum, Eob(OPT_USE_ALL, OPT_LOCK_ACCUM, _T("--lock_accum"), false, SO_NONE, "\t--lock_accum Lock threads when accumulating to the histogram using the CPU. This will drop performance to that of single threading [default: false].\n")); INITBOOLOPTION(DumpKernel, Eob(OPT_USE_RENDER, OPT_DUMP_KERNEL, _T("--dump_kernel"), false, SO_NONE, "\t--dump_kernel Print the iteration kernel string when using OpenCL (ignored for CPU) [default: false].\n")); //Int. @@ -348,10 +348,10 @@ public: INITSTRINGOPTION(Suffix, Eos(OPT_RENDER_ANIM, OPT_SUFFIX, _T("--suffix"), "", SO_REQ_SEP, "\t--suffix= Suffix to append to all output files.\n")); INITSTRINGOPTION(Format, Eos(OPT_RENDER_ANIM, OPT_FORMAT, _T("--format"), "png", SO_REQ_SEP, "\t--format= Format of the output file. Valid values are: bmp, jpg, png, ppm [default: jpg].\n")); INITSTRINGOPTION(PalettePath, Eos(OPT_USE_ALL, OPT_PALETTE_FILE, _T("--flam3_palettes"), "flam3-palettes.xml", SO_REQ_SEP, "\t--flam3_palettes= Path and name of the palette file [default: flam3-palettes.xml].\n")); - INITSTRINGOPTION(PaletteImage, Eos(OPT_USE_ALL, OPT_PALETTE_IMAGE, _T("--image"), "", SO_REQ_SEP, "\t--image= Replace palette with png, jpg, or ppm image.\n")); - INITSTRINGOPTION(Id, Eos(OPT_USE_ALL, OPT_ID, _T("--id"), "", SO_REQ_SEP, "\t--id= ID to use in tags.\n")); - INITSTRINGOPTION(Url, Eos(OPT_USE_ALL, OPT_URL, _T("--url"), "", SO_REQ_SEP, "\t--url= URL to use in tags / img comments.\n")); - INITSTRINGOPTION(Nick, Eos(OPT_USE_ALL, OPT_NICK, _T("--nick"), "", SO_REQ_SEP, "\t--nick= Nickname to use in tags / img comments.\n")); + //INITSTRINGOPTION(PaletteImage, Eos(OPT_USE_ALL, OPT_PALETTE_IMAGE, _T("--image"), "", SO_REQ_SEP, "\t--image= Replace palette with png, jpg, or ppm image.\n")); + INITSTRINGOPTION(Id, Eos(OPT_USE_ALL, OPT_ID, _T("--id"), "", SO_REQ_SEP, "\t--id= ID to use in tags / image comments.\n")); + INITSTRINGOPTION(Url, Eos(OPT_USE_ALL, OPT_URL, _T("--url"), "", SO_REQ_SEP, "\t--url= URL to use in tags / image comments.\n")); + INITSTRINGOPTION(Nick, Eos(OPT_USE_ALL, OPT_NICK, _T("--nick"), "", SO_REQ_SEP, "\t--nick= Nickname to use in tags / image comments.\n")); INITSTRINGOPTION(Comment, Eos(OPT_USE_GENOME, OPT_COMMENT, _T("--comment"), "", SO_REQ_SEP, "\t--comment= Comment to use in tags.\n")); INITSTRINGOPTION(TemplateFile, Eos(OPT_USE_GENOME, OPT_TEMPLATE, _T("--template"), "", SO_REQ_SEP, "\t--template= Apply defaults based on this flame.\n")); @@ -472,7 +472,7 @@ public: PARSESTRINGOPTION(OPT_SUFFIX, Suffix); PARSESTRINGOPTION(OPT_FORMAT, Format); PARSESTRINGOPTION(OPT_PALETTE_FILE, PalettePath); - PARSESTRINGOPTION(OPT_PALETTE_IMAGE, PaletteImage); + //PARSESTRINGOPTION(OPT_PALETTE_IMAGE, PaletteImage); PARSESTRINGOPTION(OPT_ID, Id); PARSESTRINGOPTION(OPT_URL, Url); PARSESTRINGOPTION(OPT_NICK, Nick); @@ -639,8 +639,8 @@ public: EmberOptionEntry DumpKernel; EmberOptionEntry Symmetry;//Value int. - EmberOptionEntry SheepGen;//Value int. - EmberOptionEntry SheepId;//Value int. + EmberOptionEntry SheepGen; + EmberOptionEntry SheepId; EmberOptionEntry Platform;//Value unsigned int. EmberOptionEntry Device; EmberOptionEntry Seed; @@ -682,7 +682,7 @@ public: EmberOptionEntry Suffix; EmberOptionEntry Format; EmberOptionEntry PalettePath; - EmberOptionEntry PaletteImage; + //EmberOptionEntry PaletteImage; EmberOptionEntry Id; EmberOptionEntry Url; EmberOptionEntry Nick; diff --git a/Source/EmberTester/EmberTester.cpp b/Source/EmberTester/EmberTester.cpp index 734c5a4..1780ce7 100644 --- a/Source/EmberTester/EmberTester.cpp +++ b/Source/EmberTester/EmberTester.cpp @@ -198,7 +198,7 @@ void MakeTestAllVarsRegPrePostComboFile(const string& filename) ss << index << "_" << regVar->Name(); ember1.m_Name = ss.str(); ss.str(""); - ember1.m_Palette = *paletteList.GetPalette(index % paletteList.Count()); + ember1.m_Palette = *paletteList.GetPalette(index % paletteList.Size()); index++; embers.push_back(ember1); } diff --git a/Source/Fractorium/FinalRenderEmberController.cpp b/Source/Fractorium/FinalRenderEmberController.cpp index ba0753e..47bf421 100644 --- a/Source/Fractorium/FinalRenderEmberController.cpp +++ b/Source/Fractorium/FinalRenderEmberController.cpp @@ -155,7 +155,7 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD m_GuiState = m_FinalRenderDialog->State();//Cache render settings from the GUI before running. bool doAll = m_GuiState.m_DoAll && m_EmberFile.Size() > 1; unsigned int currentStripForProgress = 0;//Sort of a hack to get the strip value to the progress function. - QString path = EmberFile::UniqueFilename(doAll ? ComposePath(QString::fromStdString(m_EmberFile.m_Embers[0].m_Name)) : ComposePath(Name())); + QString path = doAll ? ComposePath(QString::fromStdString(m_EmberFile.m_Embers[0].m_Name)) : ComposePath(Name()); QString backup = path + "_backup.flame"; //Save backup Xml. @@ -219,7 +219,7 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD //Render each image, cancelling if m_Run ever gets set to false. for (i = 0; i < m_EmberFile.Size() && m_Run; i++) { - Output("Image " + ToString(m_FinishedImageCount) + ":\n" + EmberFile::UniqueFilename(ComposePath(QString::fromStdString(m_EmberFile.m_Embers[i].m_Name)))); + Output("Image " + ToString(m_FinishedImageCount) + ":\n" + ComposePath(QString::fromStdString(m_EmberFile.m_Embers[i].m_Name))); m_Renderer->Reset();//Have to manually set this since the ember is not set each time through. m_RenderTimer.Tic();//Toc() is called in RenderComplete(). @@ -244,7 +244,7 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD //Render each image, cancelling if m_Run ever gets set to false. for (i = 0; i < m_EmberFile.Size() && m_Run; i++) { - Output("Image " + ToString(m_FinishedImageCount) + ":\n" + EmberFile::UniqueFilename(ComposePath(QString::fromStdString(m_EmberFile.m_Embers[i].m_Name)))); + Output("Image " + ToString(m_FinishedImageCount) + ":\n" + ComposePath(QString::fromStdString(m_EmberFile.m_Embers[i].m_Name))); m_Renderer->SetEmber(m_EmberFile.m_Embers[i]); m_Renderer->PrepFinalAccumVector(m_FinalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run(). m_Stats.Clear(); @@ -272,7 +272,7 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD m_Renderer->PrepFinalAccumVector(m_FinalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run(). m_Stats.Clear(); Memset(m_FinalImage); - Output(EmberFile::UniqueFilename(ComposePath(QString::fromStdString(m_Ember->m_Name)))); + Output(ComposePath(QString::fromStdString(m_Ember->m_Name))); m_RenderTimer.Tic();//Toc() is called in RenderComplete(). StripsRender(m_Renderer.get(), *m_Ember, m_FinalImage, 0, m_GuiState.m_Strips, m_GuiState.m_YAxisUp, @@ -496,7 +496,7 @@ void FinalRenderEmberController::SyncCurrentToGui() m_FinalRenderDialog->Scale(m_Ember->ScaleType()); m_FinalRenderDialog->m_QualitySpin->SetValueStealth(m_Ember->m_Quality); m_FinalRenderDialog->m_SupersampleSpin->SetValueStealth(m_Ember->m_Supersample); - m_FinalRenderDialog->Path(EmberFile::UniqueFilename(ComposePath(Name()))); + m_FinalRenderDialog->Path(ComposePath(Name())); } /// @@ -606,7 +606,7 @@ QString FinalRenderEmberController::ComposePath(const QString& name) QString path = MakeEnd(m_Settings->SaveFolder(), '/');//Base path. QString full = path + m_FinalRenderDialog->Prefix() + name + m_FinalRenderDialog->Suffix() + "." + m_FinalRenderDialog->Ext(); - return full; + return EmberFile::UniqueFilename(full); } /// @@ -635,7 +635,7 @@ template void FinalRenderEmberController::RenderComplete(Ember& ember) { string renderTimeString = m_RenderTimer.Format(m_RenderTimer.Toc()), totalTimeString; - QString status, filename = EmberFile::UniqueFilename(ComposePath(QString::fromStdString(ember.m_Name))); + QString status, filename = ComposePath(QString::fromStdString(ember.m_Name)); QString itersString = ToString(m_Stats.m_Iters); QString itersPerSecString = ToString(size_t(m_Stats.m_Iters / (m_Stats.m_IterMs / 1000.0))); diff --git a/Source/Fractorium/Fractorium.h b/Source/Fractorium/Fractorium.h index 856b956..b9a36fd 100644 --- a/Source/Fractorium/Fractorium.h +++ b/Source/Fractorium/Fractorium.h @@ -221,6 +221,8 @@ public slots: void OnPaletteAdjust(int d); void OnPaletteCellClicked(int row, int col); void OnPaletteCellDoubleClicked(int row, int col); + void OnPaletteRandomSelectButtonClicked(bool checked); + void OnPaletteRandomAdjustButtonClicked(bool checked); //Library. void OnEmberTreeItemChanged(QTreeWidgetItem* item, int col); diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui index 0be47d3..aecbdc9 100644 --- a/Source/Fractorium/Fractorium.ui +++ b/Source/Fractorium/Fractorium.ui @@ -2314,6 +2314,9 @@ SpinBox Color + + QFormLayout::AllNonFixedFieldsGrow + 6 @@ -2326,192 +2329,6 @@ SpinBox 6 - - - - - 0 - 0 - - - - - 0 - 45 - - - - - 16777215 - 68 - - - - - true - - - - Qt::NoFocus - - - - - - QFrame::Panel - - - QFrame::Plain - - - 1 - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - false - - - QAbstractItemView::NoEditTriggers - - - false - - - false - - - false - - - false - - - QAbstractItemView::NoSelection - - - QAbstractItemView::ScrollPerPixel - - - QAbstractItemView::ScrollPerPixel - - - true - - - Qt::SolidLine - - - false - - - false - - - 2 - - - false - - - false - - - 110 - - - false - - - 27 - - - true - - - false - - - 22 - - - false - - - 22 - - - false - - - - Color Speed - - - - - Opacity - - - - - Direct Color - - - - - Field - - - - - - - - - - Color Speed - - - - - 0 - - - - true - - - - AlignLeft|AlignVCenter - - - - - Opacity - - - - - 0 - - - - - Direct Color - - - - - 0 - - - - @@ -2731,6 +2548,58 @@ SpinBox + + + 0 + 0 + + + + + 162 + 18 + + + + + 16777215 + 18 + + + + Qt::NoFocus + + + 0 + + + 255 + + + 1 + + + 10 + + + 128 + + + true + + + Qt::Horizontal + + + false + + + false + + + + + 0 @@ -2740,30 +2609,179 @@ SpinBox 0 - 16 + 45 16777215 - 16 + 68 + + + true + + - Qt::StrongFocus + Qt::NoFocus - - 255 + + - - 128 + + QFrame::Panel - - Qt::Horizontal + + QFrame::Plain - + + 1 + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + false + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + false + + + false + + + QAbstractItemView::NoSelection + + + QAbstractItemView::ScrollPerPixel + + + QAbstractItemView::ScrollPerPixel + + + true + + + Qt::SolidLine + + + false + + + false + + + 2 + + + false + + + false + + + 110 + + + false + + + 27 + + + true + + + false + + + 22 + + + false + + + 22 + + + false + + + + Color Speed + + + + + Opacity + + + + + Direct Color + + + + + Field + + + + + + + + + + Color Speed + + + + + 0 + + + + true + + + + AlignLeft|AlignVCenter + + + + + Opacity + + + + + 0 + + + + + Direct Color + + + + + 0 + + @@ -3214,36 +3232,6 @@ SpinBox 1 - - - 0.5 - - - - - 0.25 - - - - - 0.1 - - - - - 0.05 - - - - - 0.025 - - - - - 0.01 - - @@ -3818,36 +3806,6 @@ SpinBox 1 - - - 0.5 - - - - - 0.25 - - - - - 0.1 - - - - - 0.05 - - - - - 0.025 - - - - - 0.01 - - @@ -4029,7 +3987,7 @@ SpinBox - true + false Show @@ -4050,7 +4008,7 @@ SpinBox - true + false Current @@ -4619,7 +4577,7 @@ SpinBox Palette - + QLayout::SetDefaultConstraint @@ -4638,6 +4596,88 @@ SpinBox 6 + + + + + 0 + 0 + + + + + 0 + 19 + + + + + 16777215 + 19 + + + + Qt::NoFocus + + + QFrame::Panel + + + QFrame::Plain + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::NoSelection + + + QAbstractItemView::ScrollPerPixel + + + QAbstractItemView::ScrollPerPixel + + + false + + + false + + + 1 + + + 2 + + + false + + + true + + + false + + + 19 + + + 19 + + + + + + @@ -4771,7 +4811,7 @@ SpinBox - + Qt::StrongFocus @@ -4846,86 +4886,37 @@ SpinBox - - - - 0 - 0 - + + + 4 - - - 0 - 19 - + + 0 - - - 16777215 - 19 - + + 0 - - Qt::NoFocus - - - QFrame::Panel - - - QFrame::Plain - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - false - - - QAbstractItemView::NoEditTriggers - - - QAbstractItemView::NoSelection - - - QAbstractItemView::ScrollPerPixel - - - QAbstractItemView::ScrollPerPixel - - - false - - - false - - - 1 - - - 2 - - - false - - - true - - - false - - - 19 - - - 19 - - - - - + + + + Select a random palette from the list + + + Random Palette + + + + + + + Random Adjustment + + + false + + + + diff --git a/Source/Fractorium/FractoriumPalette.cpp b/Source/Fractorium/FractoriumPalette.cpp index fe70f64..7965a07 100644 --- a/Source/Fractorium/FractoriumPalette.cpp +++ b/Source/Fractorium/FractoriumPalette.cpp @@ -27,6 +27,9 @@ void Fractorium::InitPaletteUI() SetupSpinner(table, this, row, 3, m_PaletteContrastSpin, spinHeight, -100, 100, 1, SIGNAL(valueChanged(int)), SLOT(OnPaletteAdjust(int)), true, 0, 0, 0); SetupSpinner(table, this, row, 3, m_PaletteBlurSpin, spinHeight, 0, 127, 1, SIGNAL(valueChanged(int)), SLOT(OnPaletteAdjust(int)), true, 0, 0, 0); SetupSpinner(table, this, row, 3, m_PaletteFrequencySpin, spinHeight, 1, 10, 1, SIGNAL(valueChanged(int)), SLOT(OnPaletteAdjust(int)), true, 1, 1, 1); + + connect(ui.PaletteRandomSelect, SIGNAL(clicked(bool)), this, SLOT(OnPaletteRandomSelectButtonClicked(bool)), Qt::QueuedConnection); + connect(ui.PaletteRandomAdjust, SIGNAL(clicked(bool)), this, SLOT(OnPaletteRandomAdjustButtonClicked(bool)), Qt::QueuedConnection); } /// @@ -55,7 +58,7 @@ bool FractoriumEmberController::InitPaletteTable(const string& s) palettePreviewTable->setItem(0, 1, previewPaletteItem); //Palette list table. - paletteTable->setRowCount(m_PaletteList.Count()); + paletteTable->setRowCount(m_PaletteList.Size()); paletteTable->setColumnWidth(1, 260);//256 plus small margin on each side. paletteTable->horizontalHeader()->setSectionsClickable(false); @@ -70,7 +73,7 @@ bool FractoriumEmberController::InitPaletteTable(const string& s) paletteTable->setHorizontalHeaderItem(1, paletteHeader); //Palette list table. - for (size_t i = 0; i < m_PaletteList.Count(); i++) + for (size_t i = 0; i < m_PaletteList.Size(); i++) { Palette* p = m_PaletteList.GetPalette(i); vector v = p->MakeRgbPaletteBlock(PALETTE_CELL_HEIGHT); @@ -220,6 +223,52 @@ void Fractorium::OnPaletteCellDoubleClicked(int row, int col) OnPaletteCellClicked(row, col); } +/// +/// Set the selected palette to a randomly selected one, +/// applying any adjustments previously specified. +/// Called when the Random Palette button is clicked. +/// Resets the rendering process. +/// +/// The current row selected +void Fractorium::OnPaletteRandomSelectButtonClicked(bool checked) +{ + unsigned int i = 0; + int rowCount = ui.PaletteListTable->rowCount() - 1; + + while ((i = QTIsaac::GlobalRand->Rand(rowCount)) == m_PreviousPaletteRow); + + OnPaletteCellClicked(i, 1); +} + +/// +/// Apply random adjustments to the selected palette. +/// Called when the Random Adjustment button is clicked. +/// Resets the rendering process. +/// +void Fractorium::OnPaletteRandomAdjustButtonClicked(bool checked) +{ + QTIsaac* gRand = QTIsaac::GlobalRand.get(); + + m_PaletteHueSpin->setValue(-180 + gRand->Rand(361)); + m_PaletteSaturationSpin->setValue(-50 + gRand->Rand(101));//Full range of these leads to bad palettes, so clamp range. + m_PaletteBrightnessSpin->setValue(-50 + gRand->Rand(101)); + m_PaletteContrastSpin->setValue(-50 + gRand->Rand(101)); + + //Doing frequency and blur together gives bad palettes that are just a solid color. + if (gRand->RandBit()) + { + m_PaletteBlurSpin->setValue(gRand->Rand(21)); + m_PaletteFrequencySpin->setValue(1); + } + else + { + m_PaletteBlurSpin->setValue(0); + m_PaletteFrequencySpin->setValue(1 + gRand->Rand(10)); + } + + OnPaletteAdjust(0); +} + /// /// Reset the palette controls. /// Usually in response to a palette cell double click. diff --git a/Source/Fractorium/FractoriumParams.cpp b/Source/Fractorium/FractoriumParams.cpp index 4c10628..8201fc0 100644 --- a/Source/Fractorium/FractoriumParams.cpp +++ b/Source/Fractorium/FractoriumParams.cpp @@ -242,7 +242,7 @@ void Fractorium::OnCenterXChanged(double d) { m_Controller->CenterXChanged(d); } /// Resets the rendering process. /// /// The y offset value -template void FractoriumEmberController::CenterYChanged(double d) { Update([&] { m_Ember.m_CenterY = d; }); } +template void FractoriumEmberController::CenterYChanged(double d) { Update([&] { m_Ember.m_CenterY = m_Ember.m_RotCenterY = d; }); } void Fractorium::OnCenterYChanged(double d) { m_Controller->CenterYChanged(d); } /// @@ -493,7 +493,7 @@ template void FractoriumEmberController::SetCenter(double x, double y) { m_Ember.m_CenterX = x; - m_Ember.m_CenterY = y; + m_Ember.m_CenterY = m_Ember.m_RotCenterY = y; m_Fractorium->m_CenterXSpin->SetValueStealth(x);//Don't trigger a redraw twice. m_Fractorium->m_CenterYSpin->SetValueStealth(y); @@ -581,7 +581,7 @@ void FractoriumEmberController::ParamsToEmber(Ember& ember) ember.m_FinalRasW = m_Fractorium->m_WidthSpin->value();//Geometry. ember.m_FinalRasH = m_Fractorium->m_HeightSpin->value(); ember.m_CenterX = m_Fractorium->m_CenterXSpin->value(); - ember.m_CenterY = m_Fractorium->m_CenterYSpin->value(); + ember.m_CenterY = ember.m_RotCenterY = m_Fractorium->m_CenterYSpin->value(); ember.m_PixelsPerUnit = m_Fractorium->m_ScaleSpin->value(); ember.m_Zoom = m_Fractorium->m_ZoomSpin->value(); ember.m_Rotate = m_Fractorium->m_RotateSpin->value(); diff --git a/Source/Fractorium/FractoriumXformsAffine.cpp b/Source/Fractorium/FractoriumXformsAffine.cpp index 2b8207a..77defc7 100644 --- a/Source/Fractorium/FractoriumXformsAffine.cpp +++ b/Source/Fractorium/FractoriumXformsAffine.cpp @@ -49,6 +49,18 @@ void Fractorium::InitXformsAffineUI() ui.PostMoveCombo->setValidator(postMoveVal); ui.PostScaleCombo->setValidator(postScaleVal); + QStringList moveList; + + moveList.append(ToString(0.5)); + moveList.append(ToString(0.25)); + moveList.append(ToString(0.1)); + moveList.append(ToString(0.05)); + moveList.append(ToString(0.025)); + moveList.append(ToString(0.01)); + + ui.PreMoveCombo->addItems(moveList); + ui.PostMoveCombo->addItems(moveList); + connect(ui.PreFlipHorizontalButton, SIGNAL(clicked(bool)), this, SLOT(OnFlipHorizontalButtonClicked(bool)), Qt::QueuedConnection); connect(ui.PreFlipVerticalButton, SIGNAL(clicked(bool)), this, SLOT(OnFlipVerticalButtonClicked(bool)), Qt::QueuedConnection); connect(ui.PreRotate90CButton, SIGNAL(clicked(bool)), this, SLOT(OnRotate90CButtonClicked(bool)), Qt::QueuedConnection); diff --git a/Source/Fractorium/FractoriumXformsColor.cpp b/Source/Fractorium/FractoriumXformsColor.cpp index 32cfcfd..a7bcee4 100644 --- a/Source/Fractorium/FractoriumXformsColor.cpp +++ b/Source/Fractorium/FractoriumXformsColor.cpp @@ -15,12 +15,12 @@ void Fractorium::InitXformsColorUI() ui.XformPaletteRefTable->setItem(0, 0, m_PaletteRefItem); ui.XformPaletteRefTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); connect(ui.XformPaletteRefTable->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), this, SLOT(OnXformRefPaletteResized(int, int, int)), Qt::QueuedConnection); - + SetupSpinner(ui.XformColorIndexTable, this, row, 1, m_XformColorIndexSpin, spinHeight, 0, 1, 0.01, SIGNAL(valueChanged(double)), SLOT(OnXformColorIndexChanged(double)), false, 0, 1, 0); SetupSpinner(ui.XformColorValuesTable, this, row, 1, m_XformColorSpeedSpin, spinHeight, -1, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformColorSpeedChanged(double)), true, 0.5, 0.5, 0.5); SetupSpinner(ui.XformColorValuesTable, this, row, 1, m_XformOpacitySpin, spinHeight, 0, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformOpacityChanged(double)), true, 1, 1, 0); SetupSpinner(ui.XformColorValuesTable, this, row, 1, m_XformDirectColorSpin, spinHeight, 0, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformDirectColorChanged(double)), true, 1, 1, 0); - + m_XformColorIndexSpin->setDecimals(3); m_XformColorSpeedSpin->setDecimals(3); m_XformOpacitySpin->setDecimals(3); diff --git a/Source/Fractorium/FractoriumXformsXaos.cpp b/Source/Fractorium/FractoriumXformsXaos.cpp index 9a389fd..325a141 100644 --- a/Source/Fractorium/FractoriumXformsXaos.cpp +++ b/Source/Fractorium/FractoriumXformsXaos.cpp @@ -189,6 +189,7 @@ void Fractorium::OnClearXaosButtonClicked(bool checked) { m_Controller->ClearXao /// Set all xaos values to random numbers. /// There is a 50% chance they're set to 0 or 1, and /// 50% that they're 0-3. +/// Resets the rendering process. /// /// Ignored template diff --git a/Source/Fractorium/GLWidget.cpp b/Source/Fractorium/GLWidget.cpp index f546e94..8cbdf06 100644 --- a/Source/Fractorium/GLWidget.cpp +++ b/Source/Fractorium/GLWidget.cpp @@ -633,7 +633,7 @@ void GLEmberController::MouseMove(QMouseEvent* e) v2T v2 = rotMat.TransformVector(v1); ember->m_CenterX = v2.x; - ember->m_CenterY = v2.y; + ember->m_CenterY = ember->m_RotCenterY = v2.y; m_FractoriumEmberController->SetCenter(ember->m_CenterX, ember->m_CenterY);//Will restart the rendering process. } else if (m_DragState == DragRotateScale)//Rotating and scaling the whole image.