Working on adding mouse-panning and zoom.
This commit is contained in:
@@ -35,6 +35,7 @@ enum class Fractal {
|
||||
MandelbrotSet, JuliaSet
|
||||
};
|
||||
|
||||
/// This class represents the FractalApp program state.
|
||||
class FractalInspectorApp : public ReWindow::OpenGLWindow {
|
||||
protected:
|
||||
JUI::Scene *scene;
|
||||
@@ -59,10 +60,13 @@ protected:
|
||||
Color4 u_rgb_4 = Colors::Green;
|
||||
Vector2 u_julia_set {0,0};
|
||||
Vector2 u_julia_value {0,0};
|
||||
bool panning = false;
|
||||
|
||||
Fractal current_fractal = Fractal::MandelbrotSet;
|
||||
|
||||
void OnShaderLoadFail(const std::string&, const std::string&);
|
||||
public:
|
||||
FractalInspectorApp();
|
||||
FractalInspectorApp(int width, int height);
|
||||
|
||||
/// Returns a full-path file name for a GLSL vertex shader, from a given prefix name.
|
||||
static std::filesystem::path VertexShaderFilepathFromPrefixName(const std::string &name);
|
||||
@@ -101,6 +105,8 @@ public:
|
||||
/// Performs a logic update.
|
||||
void Update(float elapsed);
|
||||
|
||||
float ReadableScale();
|
||||
|
||||
/// Pushes updated shader paramters to the OpenGL shader program.
|
||||
void UpdateShaderUniforms(float elapsed);
|
||||
|
||||
|
7
main.cpp
7
main.cpp
@@ -11,7 +11,12 @@
|
||||
int main(int argc, char** argv) {
|
||||
ReWindow::Logger::Debug.EnableConsole(false);
|
||||
|
||||
auto* program = new FractalInspectorApp();
|
||||
int default_app_width = 1080;
|
||||
int default_app_height = 768;
|
||||
|
||||
// TODO: Create AppConfig struct and pass to constructor.
|
||||
|
||||
auto* program = new FractalInspectorApp(default_app_width, default_app_height);
|
||||
|
||||
program->Open();
|
||||
program->SetFullscreen(false);
|
||||
|
@@ -68,6 +68,9 @@ float iterate_mandelbrot(vec2 p) {
|
||||
void main() {
|
||||
vec2 R = u_resolution.xy;
|
||||
|
||||
// Unused as of yet, see TODOs for what and why.
|
||||
float scale = (3.0 - u_scale);
|
||||
|
||||
vec2 uv = (u_scale * gl_FragCoord.xy - R - 1.) / R.y - u_translation;
|
||||
|
||||
float n = iterate_mandelbrot(uv) / N;
|
||||
|
@@ -1,15 +1,21 @@
|
||||
#include <FractalApp.hpp>
|
||||
|
||||
FractalInspectorApp::FractalInspectorApp(): ReWindow::OpenGLWindow("ReShader", 1800, 1000, 2, 1) {
|
||||
Shader::OnCompilationErrorMessage += [this](std::string type, std::string infoLog) {
|
||||
auto log_lines = misc::string_expand(infoLog, '\n');
|
||||
console->Log(type, Colors::Red);
|
||||
std::cerr << type << std::endl;
|
||||
for (auto line: log_lines) {
|
||||
console->Log(line, Colors::Red);
|
||||
std::cerr << line << std::endl;
|
||||
}
|
||||
};
|
||||
#define GL_VER_MAJOR 2
|
||||
#define GL_VER_MINOR 1
|
||||
|
||||
void FractalInspectorApp::OnShaderLoadFail(const std::string& type, const std::string& infoLog) {
|
||||
auto log_lines = misc::string_expand(infoLog, '\n');
|
||||
console->Log(type, Colors::Red);
|
||||
std::cerr << type << std::endl;
|
||||
for (auto line: log_lines) {
|
||||
console->Log(line, Colors::Red);
|
||||
std::cerr << line << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
FractalInspectorApp::FractalInspectorApp(int width, int height):
|
||||
OpenGLWindow("FractalInspector",width, height, GL_VER_MAJOR, GL_VER_MINOR) {
|
||||
Shader::OnCompilationErrorMessage += [this] (auto... args) { OnShaderLoadFail(args...);};
|
||||
|
||||
u_time = 0;
|
||||
}
|
||||
@@ -439,11 +445,20 @@ void FractalInspectorApp::Update(float elapsed) {
|
||||
|
||||
int fps = 1.f / elapsed;
|
||||
|
||||
std::string fps_text = std::format("FPS: {}", fps);
|
||||
|
||||
// TODO: Consider moving this logic deeper into the shader to make it easier to work with.
|
||||
float readable_scale = Math::Round(ReadableScale(), 3);
|
||||
|
||||
std::string fps_text = std::format("Pos: {},{} Zoom: {}x FPS: {}",
|
||||
Math::Round(u_translation.x, 2), Math::Round(u_translation.y, 2), readable_scale, fps);
|
||||
|
||||
fps_label->SetContent(fps_text);
|
||||
}
|
||||
|
||||
float FractalInspectorApp::ReadableScale() {
|
||||
return 3.f - u_scale;
|
||||
}
|
||||
|
||||
void FractalInspectorApp::UpdateShaderUniforms(float elapsed) {
|
||||
Vector2 u_res = Vector2(GetSize().x, GetSize().y);
|
||||
|
||||
@@ -507,27 +522,71 @@ void FractalInspectorApp::OnRefresh(float elapsed) {
|
||||
this->SwapBuffers();
|
||||
}
|
||||
|
||||
enum JUI::MouseButton ToJUIEnum(const MouseButton& btn) {
|
||||
|
||||
if (btn == MouseButtons::Left) return JUI::MouseButton::Left;
|
||||
if (btn == MouseButtons::Middle) return JUI::MouseButton::Middle;
|
||||
if (btn == MouseButtons::Right) return JUI::MouseButton::Right;
|
||||
|
||||
// Default condition.
|
||||
return JUI::MouseButton::Left;
|
||||
}
|
||||
|
||||
void FractalInspectorApp::OnMouseButtonDown(const ReWindow::MouseButtonDownEvent &e) {
|
||||
if (e.Button == MouseButtons::Left)
|
||||
|
||||
auto btn = ToJUIEnum(e.Button);
|
||||
|
||||
if (scene->ObserveMouseInput(btn, true))
|
||||
return;
|
||||
|
||||
if (btn == JUI::MouseButton::Right)
|
||||
panning = true;
|
||||
|
||||
|
||||
/*if (e.Button == MouseButtons::Left)
|
||||
scene->ObserveMouseInput(JUI::MouseButton::Left, true);
|
||||
if (e.Button == MouseButtons::Middle)
|
||||
scene->ObserveMouseInput(JUI::MouseButton::Middle, true);
|
||||
if (e.Button == MouseButtons::Right)
|
||||
scene->ObserveMouseInput(JUI::MouseButton::Right, true);
|
||||
scene->ObserveMouseInput(JUI::MouseButton::Right, true);*/
|
||||
}
|
||||
|
||||
void FractalInspectorApp::OnMouseButtonUp(const ReWindow::MouseButtonUpEvent &e) {
|
||||
if (e.Button == MouseButtons::Left)
|
||||
|
||||
|
||||
auto btn = ToJUIEnum(e.Button);
|
||||
|
||||
if (scene->ObserveMouseInput(btn, true))
|
||||
return;
|
||||
|
||||
if (btn == JUI::MouseButton::Right)
|
||||
panning = false;
|
||||
|
||||
/*if (e.Button == MouseButtons::Left)
|
||||
scene->ObserveMouseInput(JUI::MouseButton::Left, false);
|
||||
if (e.Button == MouseButtons::Middle)
|
||||
scene->ObserveMouseInput(JUI::MouseButton::Middle, false);
|
||||
if (e.Button == MouseButtons::Right)
|
||||
scene->ObserveMouseInput(JUI::MouseButton::Right, false);
|
||||
scene->ObserveMouseInput(JUI::MouseButton::Right, false);*/
|
||||
}
|
||||
|
||||
Vector2 last{0,0};
|
||||
|
||||
void FractalInspectorApp::OnMouseMove(const ReWindow::MouseMoveEvent &e) {
|
||||
Vector2 nmp = Vector2(e.Position.x, e.Position.y);
|
||||
scene->ObserveMouseMovement(nmp);
|
||||
if (scene->ObserveMouseMovement(nmp))
|
||||
return;
|
||||
|
||||
// TODO: e.Delta is always 0, investigate in JUI.
|
||||
Vector2 delta = nmp - last;
|
||||
|
||||
float bias_slowdown_as_we_zoom_in = 1.125f;
|
||||
float base_slowdown = 0.005;
|
||||
|
||||
if (panning)
|
||||
u_translation += delta*(1.f / ReadableScale()*bias_slowdown_as_we_zoom_in)*base_slowdown;
|
||||
|
||||
last = nmp;
|
||||
}
|
||||
|
||||
void FractalInspectorApp::OnKeyDown(const ReWindow::KeyDownEvent &e) {
|
||||
|
Reference in New Issue
Block a user