Skip to content

Commit

Permalink
v1.0.9 | 2024/03/31 22:59 | Added a Julia Cordinate Point feature. St…
Browse files Browse the repository at this point in the history
…arted work on making a better frame timer/pacer
  • Loading branch information
ZERICO2005 committed Apr 1, 2024
1 parent fa5b547 commit 206e037
Show file tree
Hide file tree
Showing 14 changed files with 325 additions and 64 deletions.
17 changes: 7 additions & 10 deletions src/Common_Def.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ typedef int32_t dim32_t;
// Right Circular Shift
#define ROR(n,b) (((n) >> (b)) | ((n) << ((sizeof(n) * CHAR_BIT) - (b))))

inline const char* bool_Text(const bool& b) { return b ? "true" : "false"; }
inline const char* Bool_Text(const bool& b) { return b ? "True" : "False"; }
inline const char* BOOL_Text(const bool& b) { return b ? "TRUE" : "FALSE"; }
constexpr inline const char* bool_Text(const bool& b) { return b ? "true" : "false"; }
constexpr inline const char* Bool_Text(const bool& b) { return b ? "True" : "False"; }
constexpr inline const char* BOOL_Text(const bool& b) { return b ? "TRUE" : "FALSE"; }

// Replace with valueClamp<cast, minimum, maximum>(value)

Expand Down Expand Up @@ -159,13 +159,10 @@ typedef int32_t dim32_t;
// Returns the time in seconds
fp64 getDecimalTime();

inline nano64_t SECONDS_TO_NANO(fp64 t) { return (nano64_t)((t) * 1.0e9); }
inline fp64 NANO_TO_SECONDS(nano64_t t) { return ((fp64)(t) / 1.0e9); }

// // Callocs the date and time in UTC
// const char* getDateAndTimeUTC(
// char DateDelimiter = '-', char DateSeparator = '_', char TimeDelimiter = '-'
// );
constexpr inline nano64_t SECONDS_TO_NANO(fp64 s) { return (nano64_t)(s * 1.0e9); }
constexpr inline fp64 NANO_TO_SECONDS(nano64_t t) { return (fp64)t / 1.0e9; }
constexpr inline nano64_t FRAMERATE_TO_NANO(fp64 f) { return (nano64_t)(1.0e9 / f); }
constexpr inline fp64 NANO_TO_FRAMERATE(nano64_t t) { return (1.0e9) / (fp64)t; }

/* Print Functions */
#define printFlush(...) printf(__VA_ARGS__); fflush(stdout)
Expand Down
5 changes: 3 additions & 2 deletions src/Program_Def.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
#define PROGRAM_DATE "2024/03/31" /* YYYY/MM/DD */
#define PROGRAM_V_MAJOR 1
#define PROGRAM_V_MINOR 1
#define PROGRAM_V_PATCH 8
#define PROGRAM_V_TAG "Rev-6 Developer Alpha"
#define PROGRAM_V_PATCH 9
#define PROGRAM_V_TAG "Alpha"
#define PROGRAM_VERSION STR_N(PROGRAM_V_MAJOR) "." STR_N(PROGRAM_V_MINOR) "." STR_N(PROGRAM_V_PATCH) " " PROGRAM_V_TAG

/* float80 and float128 */
Expand All @@ -46,6 +46,7 @@
inline fp128 acos(fp128 x) { return acosq(x); }
inline fp128 atan(fp128 x) { return atanq(x); }
inline fp128 atan2(fp128 y, fp128 x) { return atan2q(y,x); }
inline fp128 hypot(fp128 x, fp128 y) { return hypotq(x,y); }
inline fp128 log(fp128 x) { return logq(x); }
inline fp128 log1p(fp128 x) { return log1pq(x); }
inline fp128 log2(fp128 x) { return log2q(x); }
Expand Down
45 changes: 38 additions & 7 deletions src/display_GUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,17 @@ void horizontal_buttons_IMGUI(ImGuiWindowFlags window_flags) {
#define FRAC frac.type.abs_mandelbrot
uint32_t renderFP = (primaryRenderData.rendering_method == Rendering_Method::CPU_Rendering) ? primaryRenderData.CPU_Precision : primaryRenderData.GPU_Precision;
const char* const renderMethod = (primaryRenderData.rendering_method == Rendering_Method::CPU_Rendering) ? "CPU" : "GPU";

static char powerText[64];
if (FRAC.polarMandelbrot) {
snprintf(powerText,sizeof(powerText),"%6.4lf",FRAC.polarPower);
}

ImGui::Text(
"Formula: %llu Power: %6.4lf Super-Sample: %u Rendering: %s fp%u",
FRAC.formula,(FRAC.polarMandelbrot ? FRAC.polarPower : (fp64)FRAC.power),primaryRenderData.sample * primaryRenderData.sample,renderMethod,renderFP
"Formula: %llu Power: %s Super-Sample: %u Rendering: %s fp%u",
FRAC.formula,(FRAC.polarMandelbrot ? powerText : getPowerText(FRAC.power)),primaryRenderData.sample * primaryRenderData.sample,renderMethod,renderFP
);
#define temp_quad_len 64
constexpr size_t temp_quad_len = 64;
static char temp_quad_r[temp_quad_len]; static char temp_quad_i[temp_quad_len];
static char temp_quad_zr[temp_quad_len]; static char temp_quad_zi[temp_quad_len];
quadmath_snprintf(temp_quad_r,temp_quad_len,"%15.12Qf",FRAC.r);
Expand Down Expand Up @@ -309,6 +315,7 @@ void Menu_Coordinates() {
ImGui_BoundWindowPosition(config_data.GUI_Settings);

if (frac.type_value == Fractal_ABS_Mandelbrot || frac.type_value == Fractal_Polar_Mandelbrot) { /* ABS and Polar */
ImGui::SeparatorText("Cordinates");
#define FRAC frac.type.abs_mandelbrot
#define NumberTextLen 64

Expand Down Expand Up @@ -341,17 +348,27 @@ void Menu_Coordinates() {
Quad_InputText("i",FRAC.i,"%35.32Qf");
ImGui::Text("Zoom:");
Float_InputText("##zoom_input",FRAC.zoom,"%.5lf",strtod);

ImGui::Text(" ");
ImGui::Text("Julia Coordinate:");
static bool useJuliaSliders = true;
if (useJuliaSliders == true) {
float input_Zreal = (fp32)FRAC.zr; float input_Zimag = (fp32)FRAC.zi;
if (ImGui::SliderFloat("zr",&input_Zreal,-2.0,2.0,"%.9f")) { FRAC.zr = (fp64)input_Zreal; }
if (ImGui::SliderFloat("zi",&input_Zimag,-2.0,2.0,"%.9f")) { FRAC.zi = (fp64)input_Zimag; }
fp32 juliaAngle = (fp32)atan2(FRAC.zi, FRAC.zr);
if (ImGui::SliderAngle("Julia Angle",&juliaAngle,-360.0f,360.0f,"%.1f deg")) {
fp128 juliaMagnitude = hypot(FRAC.zr, FRAC.zi);
fp128 juliaTheta = (fp128)juliaAngle;
FRAC.zr = juliaMagnitude * cos(juliaTheta);
FRAC.zi = juliaMagnitude * sin(juliaTheta);
}
} else {
Quad_InputText("##input_Zreal",FRAC.zr,"%35.32Qf");
Quad_InputText("##input_zimag",FRAC.zi,"%35.32Qf");
}
ImGui::Checkbox("Use Sliders", &useJuliaSliders);
ImGui::SeparatorText("Parameters");
ImGui::Text("Maximum Iterations:");
Int_InputText("##input_maxIter",FRAC.maxItr,"%u",strtoul,10);
ImGui::Text("Fractal Formula:");
Expand All @@ -364,7 +381,7 @@ void Menu_Coordinates() {
ImGui::Checkbox("Hexadecimal", &inputHexadecimal);
/* Power */
if (frac.type_value == Fractal_ABS_Mandelbrot) {
ImGui::Text("Power: %s",getPowerText((int32_t)FRAC.power));
ImGui::Text("Power: %s",getPowerText((uint32_t)FRAC.power));
Int_InputText("##input_power",FRAC.power,"%u",strtoul,10);
} else if (frac.type_value == Fractal_Polar_Mandelbrot) {
ImGui::Text("Power: %s",getPowerText(round(FRAC.polarPower)));
Expand Down Expand Up @@ -421,7 +438,7 @@ void Menu_Fractal() {
ImGui::Text("Fractal Radius: %.6lg",maxRadius);
ImGui::Text("Cardioid Location: %.6lg",minRadius);
if (Combo_FractalType == Fractal_ABS_Mandelbrot) {
ImGui::Text("Fractal Power: %s",getPowerText((int32_t)FRAC.power));
ImGui::Text("Fractal Power: %s",getPowerText((uint32_t)FRAC.power));
int temp_input_power = (int)FRAC.power;
ImGui::InputInt("##temp_input_power",&temp_input_power,1,1); FRAC.power = (uint32_t)temp_input_power;
valueClamp(FRAC.power, 2, 6); // Support up to Sextic
Expand Down Expand Up @@ -529,6 +546,8 @@ void Menu_Rendering() {
(int32_t)Master.resY, ImGui_WINDOW_MARGIN * 2, 160, 320
);

User_Rendering_Settings& Rendering_Settings = config_data.Rendering_Settings;

static const char* CPU_RenderingModes[] = {"fp32 | 10^5.7","fp64 | 10^14.4 (Default)","fp80 | 10^17.7","fp128 | 10^32.5"};
#ifndef BUILD_RELEASE
static const char* GPU_RenderingModes[] = {"fp16 | 10^1.8","fp32 | 10^5.7 (Default)","fp64 | 10^14.4"};
Expand Down Expand Up @@ -621,7 +640,7 @@ void Menu_Rendering() {
}
#endif

ImGui::Separator();
ImGui::SeparatorText("Super Screenshot Settings");

ImGui::Text("Sub Sample: %d", input_subSample * input_subSample);
if (ImGui::SliderInt("##input_subSample",&input_subSample,1,24,"")) {
Expand All @@ -646,8 +665,20 @@ void Menu_Rendering() {
// );
// }
// }
constexpr fp32 maxOutterRadius = 24.0f;
constexpr fp32 maxInnerRadius = maxOutterRadius - 1.0f;
ImGui::SeparatorText("Julia Cordinate Point");
ImGui::Checkbox("Display Julia Point", &Rendering_Settings.JuliaPoint_Enabled);
ImGui::Text("Outer-Radius:");
if (ImGui::SliderFloat("##OuterRadius",&Rendering_Settings.JuliaPoint_OuterRadius, 1.0f, maxOutterRadius, "%.2f")) {
valueClamp(Rendering_Settings.JuliaPoint_InnerRadius, 0.0f, Rendering_Settings.JuliaPoint_OuterRadius - 1.0f);
}
ImGui::Text("Inner-Radius");
if (ImGui::SliderFloat("##InnerRadius",&Rendering_Settings.JuliaPoint_InnerRadius, 0.0f, maxInnerRadius, "%.2f")) {
valueClamp(Rendering_Settings.JuliaPoint_OuterRadius, Rendering_Settings.JuliaPoint_InnerRadius + 1.0f, maxOutterRadius);
}

ImGui::Separator();
ImGui::SeparatorText("Frame Interpolation");
static const char* OpenCV_interpolation_mode_list[] = {"Nearest Neighbor (Default)","Linear","Cubic","Area","Lanczos"};
int_enum& OpenCV_interpolation_mode = config_data.Rendering_Settings.Frame_Interpolation_Method;
ImGui::Text("Frame Interpolation Method:");
Expand Down
12 changes: 0 additions & 12 deletions src/fracCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,15 @@ void calculate_GPU_Hardware_Hash(uint64_t& hash) {
fnv1a_hash_continous(hash,(uint8_t*)(void*)&
DeviceMaxComputeUnits,sizeof(DeviceMaxComputeUnits)
);
fnv1a_hash_continous(hash,(uint8_t*)(void*)&
DeviceMaxWorkGroupSize,sizeof(DeviceMaxWorkGroupSize)
);
fnv1a_hash_continous(hash,(uint8_t*)(void*)&
DeviceGlobalMemSize,sizeof(DeviceGlobalMemSize)
);
fnv1a_hash_continous(hash,(uint8_t*)(void*)&
DeviceLocalMemSize,sizeof(DeviceLocalMemSize)
);
fnv1a_hash_continous(hash,(uint8_t*)(void*)&
DeviceFP32Config,sizeof(DeviceFP32Config)
);
fnv1a_hash_continous(hash,(uint8_t*)(void*)&
DeviceFP64Config,sizeof(DeviceFP64Config)
);
fnv1a_hash_continous(hash,(uint8_t*)(void*)&
KernelWorkGroupSize,sizeof(KernelWorkGroupSize)
);
fnv1a_hash_continous(hash,(uint8_t*)(void*)&
KernelLocalMemSize,sizeof(KernelLocalMemSize)
);
}

int32_t init_OpenCL() {
Expand Down
8 changes: 4 additions & 4 deletions src/fractal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
#include "fractal.h"

/* Safe Method of accessing PowerText */
const char* getPowerText(int32_t p) {
if (p >= 0 && p <= (int32_t)ARRAY_LENGTH(PowerText)) {
const char* getPowerText(uint32_t p) {
if (p < (uint32_t)ARRAY_LENGTH(PowerText)) {
return PowerText[p];
}
return NULL;
}
const char* getPowerText(fp64 p) {
return getPowerText((int32_t)p);
return getPowerText((uint32_t)p);
}

uint64_t limitFormulaID(uint32_t power, uint64_t formula) {
Expand Down Expand Up @@ -69,7 +69,7 @@ void setDefaultParameters(Fractal_Data* frac, enum FractalTypeEnum type) {
FRAC.swapJuliaSplit = false;
FRAC.cursorZValue = false;
FRAC.showFloatingJulia = false;
FRAC.adjustZoomToPower = true;
FRAC.adjustZoomToPower = false;
FRAC.polarMandelbrot = false;
FRAC.lockToCardioid = false;
FRAC.flipCardioidSide = false;
Expand Down
10 changes: 5 additions & 5 deletions src/fractal.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ enum FractalTypeEnum {
const char* const PowerText[] = {
"Constant", "Linear" , "Quadratic", "Cubic" , "Quartic" , "Quintic" , "Sextic" , "Septic" , "Octic" , "Nonic" ,
"Decic" , "Undecic" , "Dodecic" , "Tridecic" , "Tetradecic" , "Pentadecic", "Hexadecic", "Heptadecic", "Octadecic", "Nonadecic",
"Icosic" , "Unicosic", "Duocosic" , "Triacosic", "Tetraicosic", "Pentacosic", "Hexacosic", "Heptacosic", "Octacosic", "Nonacosic"
"Icosic" , "Unicosic", "Duocosic" , "Triacosic", "Tetraicosic", "Pentacosic", "Hexacosic", "Heptacosic", "Octacosic", "Nonacosic"
};
/* Safe Method of accessing PowerText */
const char* getPowerText(int32_t p);
const char* getPowerText(uint32_t p);
const char* getPowerText(fp64 p);

inline fp64 getABSFractalMinRadius(fp64 power) {
Expand Down Expand Up @@ -150,8 +150,8 @@ void setDefaultParameters(Fractal_Data* frac, enum FractalTypeEnum type);
template <typename fpX>
void coordinate_to_pixel(fpX xI, fpX yI, int32_t* xO, int32_t* yO, const ABS_Mandelbrot* param, const Render_Data* ren) {
/* Reverses Transformations */
fpX xC = xI * cos(-(fpX)param->rot) - yI * sin(-(fpX)param->rot);
fpX yC = yI * cos(-(fpX)param->rot) + xI * sin(-(fpX)param->rot);
fpX xC = xI * cos(-(fpX)param->rot) - yI * sin(-(fpX)param->rot) - param->r;
fpX yC = yI * cos(-(fpX)param->rot) + xI * sin(-(fpX)param->rot) - param->i;
xC /= (fpX)param->sX;
yC /= (fpX)param->sY;
/* Normalizes Coordinates */
Expand All @@ -172,7 +172,7 @@ void coordinate_to_image_cordinate(fpX xI, fpX yI, fp32* xO, fp32* yO, const ABS
/* Normalizes Coordinates */
dim32_t resX = ren->resX - 1;
dim32_t resY = ren->resY - 1;
dim32_t resZ = (resX >= resY) ? resY : resX;\
dim32_t resZ = (resX >= resY) ? resY : resX;
*xO = (fp32)( (xC * pow((fpX)10.0, (fpX)param->zoom) / (fpX)2.0 * (((fpX)resZ))) + (((fpX)resX) / (fpX)2.0) );
*yO = (fp32)( (-yC * pow((fpX)10.0, (fpX)param->zoom) / (fpX)2.0 * (((fpX)resZ))) + (((fpX)resY) / (fpX)2.0) );
}
Expand Down
116 changes: 116 additions & 0 deletions src/framePacer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
** Author: zerico2005 (2023-2024)
** Project: ABS-Fractal-Explorer
** License: MIT License
** A copy of the MIT License should be included with
** this project. If not, see https://opensource.org/license/MIT
*/

#include "Common_Def.h"
#include "framePacer.hpp"

/* class Frame_Pacer */
/* public */
/* Constructors */
Frame_Pacer::Frame_Pacer() {
init_Frame_Pacer(0,0);
}

Frame_Pacer::Frame_Pacer(nano64_t frameTime, nano64_t pollTime) {
init_Frame_Pacer(frameTime, pollTime);
}

Frame_Pacer::Frame_Pacer(fp64 frameRate, fp64 pollRate) {
init_Frame_Pacer(FRAMERATE_TO_NANO(frameRate), FRAMERATE_TO_NANO(pollRate));
}


/* Variables */
nano64_t Frame_Pacer::get_FrameTime() const {
return FrameTime;
}
fp64 Frame_Pacer::get_FrameRate() const {
return NANO_TO_FRAMERATE(FrameTime);
}

void Frame_Pacer::set_FrameTime(nano64_t frameTime) {
FrameTime = frameTime;
}
void Frame_Pacer::set_FrameRate(fp64 frameRate) {
set_FrameTime(FRAMERATE_TO_NANO(frameRate));
}

/* Functions */
// Force starts the next frame
void Frame_Pacer::forceNewFrame() {
nano64_t currentTime = getNanoTime();
Frame_Start = currentTime;
Next_Frame = Frame_Start + FrameTime;

nano64_t frameTime = Frame_Start - currentTime;
update_Maximum_FrameTime(frameTime);
}
// Checks if the next frame is ready
bool Frame_Pacer::checkNewFrame() const {
return (timeUntilNextFrame() <= 0) ? true : false;
}
// Checks and starts the next frame
bool Frame_Pacer::startNewFrame() {
if (checkNewFrame() == true) {
forceNewFrame();
return true;
}
return false;
}

nano64_t Frame_Pacer::timeUntilNextFrame() const {
return Next_Frame - getNanoTime();
}
fp64 Frame_Pacer::secondsUntilNextFrame() const {
return NANO_TO_SECONDS(timeUntilNextFrame());
}

// Will yeild/sleep until the next frame
void Frame_Pacer::waitForNextFrame(nano64_t threshold) {
if (checkNewFrame() == true) { return; }
while (timeUntilNextFrame() > threshold) {
std::this_thread::yield();
}
while (checkNewFrame() == false) { /* Spin-Lock */ }
forceNewFrame();
}
void Frame_Pacer::waitForNextFrame(fp64 threshold) {
waitForNextFrame(SECONDS_TO_NANO(threshold));
}

/* Statistics */
nano64_t Frame_Pacer::get_MaximumFrameTime() const {
return Display_Maximum_FrameTime;
}
fp64 Frame_Pacer::get_MaximumFrameRate() const {
return NANO_TO_FRAMERATE(Display_Maximum_FrameTime);
}

/* private */
void Frame_Pacer::init_Frame_Pacer(nano64_t frameTime, nano64_t pollTime) {
FrameTime = frameTime;
PollTime = pollTime;

Frame_Start = getNanoTime();
Next_Frame = Frame_Start + frameTime;
Delta_Time = 0;

Display_Maximum_FrameTime = 0;
Maximum_FrameTime = 0;
Maximum_Timer = getNanoTime();
}
void Frame_Pacer::update_Maximum_FrameTime(nano64_t frameTime) {
if (frameTime > Maximum_FrameTime) {
Maximum_FrameTime = frameTime;
}
if (getNanoTime() - Maximum_Timer > PollTime) {
Maximum_Timer = getNanoTime();
Display_Maximum_FrameTime = Maximum_FrameTime;
Maximum_FrameTime = 0;
}
}
Loading

0 comments on commit 206e037

Please sign in to comment.