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.