13 Commits

Author SHA1 Message Date
f18c8c3fe3 Use JGL for more efficient rendering. 2025-01-31 19:26:11 -05:00
4f6080a962 removed unused headers 2025-01-31 17:42:35 -05:00
ffb989cd19 Update README.md 2025-01-31 17:33:02 -05:00
f204dc5898 user controlled added variable pushForce
User can user 1, 2, 3, 4 or 5 key to change the force at which the walker is pushed away from the mouse pointer when the mouse button is pressed.
2025-01-31 17:31:40 -05:00
9b06da8ee1 Update README.md 2025-01-31 15:51:00 -05:00
28a2d42369 added user interaction information 2025-01-31 14:30:05 -05:00
0be005a877 added user interaction
mouse click to blow walker away from mouse
space to reset walker to middle of the window
esc to close application
2025-01-31 14:28:14 -05:00
27dd9b3639 added trail effect 2025-01-31 14:09:33 -05:00
07c970749f Update main.cpp
render random walker as dot and added hopefully helpful comments
2025-01-31 13:47:03 -05:00
ca55970ed9 Update main.cpp
changed to using smart pointer for window in main()
2025-01-31 13:29:42 -05:00
rich
9f4b8987c0 updated to make README look more like other Redacted project READMEs! 2025-01-13 17:07:32 -05:00
mathsDOTearth
a3d67ef18a Merge remote-tracking branch 'origin/ReWindow-Integration' 2025-01-13 21:58:20 +00:00
rich
01f2acca60 changed to use smart pointer for window handle 2025-01-13 10:24:35 -05:00
4 changed files with 251 additions and 38 deletions

View File

@@ -28,20 +28,39 @@ include(cmake/CPM.cmake)
# You specify the release name to target against. See the link below for releases:
# https://git.redacted.cc/Redacted/ReWindow/releases
CPMAddPackage(
NAME mcolor
URL https://git.redacted.cc/maxine/mcolor/archive/Prerelease-5.zip
)
CPMAddPackage(
NAME ReWindow
URL URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-31.zip
URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-32.zip
)
CPMAddPackage(
NAME JGL
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-47.zip
)
add_executable(ReWalkerApp main.cpp)
target_include_directories(ReWalkerApp PUBLIC ${ReWindow_SOURCE_DIR}/include ${J3ML_SOURCE_DIR}/include)
target_include_directories(ReWalkerApp PUBLIC
${ReWindow_SOURCE_DIR}/include
${J3ML_SOURCE_DIR}/include
${mcolor_SOURCE_DIR}/include
${JGL_SOURCE_DIR}/include
)
target_link_libraries(ReWalkerApp PUBLIC J3ML ReWindowLibrary)
target_link_libraries(ReWalkerApp PUBLIC J3ML ReWindow mcolor JGL)
# simple window test
add_executable(TestWindowApp test.cpp)
target_include_directories(TestWindowApp PUBLIC ${ReWindow_SOURCE_DIR}/include ${J3ML_SOURCE_DIR}/include)
target_include_directories(TestWindowApp PUBLIC
${ReWindow_SOURCE_DIR}/include
${J3ML_SOURCE_DIR}/include
${mcolor_SOURCE_DIR}/include
)
target_link_libraries(TestWindowApp PUBLIC J3ML ReWindowLibrary)
target_link_libraries(TestWindowApp PUBLIC J3ML ReWindow)

View File

@@ -1,9 +1,42 @@
# ReWalker
ReWalker is a simple random walker program that uses ReWindow to handle windowing and mouse operations.
This is a simple random walker that has a little twist that if the user clicks the mouse over the window it "blows" the walker away from the mouse pointer.
This is a simple random walker that has a little twist that if the user clicks the mouse over the window it "blows" the walker away from the mouse pointer. Pressing the space bar will reset the walker back to the centre of the screen and pressing the esc key will close the application.
The user can user the number 1, 2, 3, 4 and 5 keys to change the force at which the walker is blown away from the mouse pointer. 1 is lowest force and 5 is highest.
test.cpp builds to TestWindowApp as a test to help me understand how ReWindow works.
main.cpp builds to ReWalkerApp which is the main random walker program.
Thanks to Bill, Josh and Maxine for sorting the correct ReWindow Integration.
## Run ReWalker
Install dependencies
```bash
Rocky/Fedora/RHEL: dnf install cmake make gcc-g++ libX11 libX11-devel mesa-libGL-devel
Pop_OS!/Ubuntu/Debian: apt-get install cmake make gcc g++ libx11-6 libx11-dev libgl-dev libxrandr-dev
```
Clone the repository
```bash
git clone https://git.redacted.cc/rich/ReWalker.git
```
Build
```bash
cd ReWalker && mkdir build && cd build && cmake .. && make
```
Run it
```bash
./ReWalkerApp
```
## Thanks
Thanks to Bill, Josh and Maxine for sorting the correct ReWindow Integration, and other things.

203
main.cpp
View File

@@ -1,53 +1,216 @@
// ReWalker
// A random walker that moves around the screen
// A random walker that moves around the screen with a fading trail and mouse interaction.
// Now with real-time adjustable push force using number keys 1-5!
// Written using Redacted ReWindow https://git.redacted.cc/Redacted/ReWindow
// Written by Rich
// With help from (and thanks to) from Maxine, Josh and Bill
#include <rewindow/types/window.h>
#include <rewindow/logger/logger.h>
#include <GL/gl.h>
#include <ReWindow/types/Window.h>
#include <ReWindow/Logger.h>
#include <JGL/JGL.h>
#include <Color4.hpp>
#include <memory>
// define window size and dot size (dot size should be odd)
// Define window size and dot size (dot size should be odd for symmetry)
#define WIDTH 800
#define HEIGHT 600
#define DOT_SIZE 5
// Define fading speed (higher = faster fading, range: 0.001 - 0.2)
#define FADE_SPEED 0.05f
constexpr unsigned int TRAIL_LENGTH = 20;
// Enable debug mode (set to 0 to disable debug output)
#define DEBUG 0
/**
* @brief Represents the walker that moves randomly on the screen.
*/
struct Walker {
float x, y;
Vector2 position{}; // Current position of the walker
Walker() : x(WIDTH / 2.0f), y(HEIGHT / 2.0f) {}
/**
* @brief Constructor initializes the walker at the center of the screen.
*/
Walker() : position(WIDTH / 2.0f, HEIGHT / 2.0f) {}
/**
* @brief Moves the walker one step in a random direction.
*/
void step() {
float angle = static_cast<float>(rand()) / RAND_MAX * 360.0f;
angle = angle * M_PI / 180.0f;
angle = Math::Radians(angle);
float dx = std::cos(angle);
float dy = std::sin(angle);
x = std::clamp(x + dx, 0.0f, static_cast<float>(WIDTH - 1));
y = std::clamp(y + dy, 0.0f, static_cast<float>(HEIGHT - 1));
// Update position and clamp within screen boundaries
position.x = std::clamp(position.x + dx, 0.0f, static_cast<float>(WIDTH - 1));
position.y = std::clamp(position.y + dy, 0.0f, static_cast<float>(HEIGHT - 1));
#if DEBUG
std::cout << "Walker Position: (" << position.x << ", " << position.y << ")\n";
#endif
}
/**
* @brief Pushes the walker away from a given (mouse) position.
* @param mouseX X coordinate of the mouse.
* @param mouseY Y coordinate of the mouse.
* @param force The force applied to push the walker away.
*/
void pushAway(float mouseX, float mouseY, float force) {
float adjustedMouseY = HEIGHT - mouseY; // Adjust for coordinate system
float deltaX = position.x - mouseX;
float deltaY = position.y - adjustedMouseY;
float distance = std::sqrt(deltaX * deltaX + deltaY * deltaY);
// Only push if the mouse is close enough
if (distance > 0.0f) {
float unitX = deltaX / distance;
float unitY = deltaY / distance;
// Apply dynamic push force
position.x = std::clamp(position.x + unitX * force, 0.0f, static_cast<float>(WIDTH - 1));
position.y = std::clamp(position.y + unitY * force, 0.0f, static_cast<float>(HEIGHT - 1));
}
}
/**
* @brief Resets the walker to the center of the screen.
*/
void resetPosition() {
position = Vector2(WIDTH / 2.0f, HEIGHT / 2.0f);
}
};
class RandomWalkerWindow : public ReWindow::RWindow {
/**
* @brief Custom ReWindow window class that manages the random walker simulation.
*/
class RandomWalkerWindow : public ReWindow::OpenGLWindow {
public:
/**
* @brief Constructor initializes the window, walker, and trail buffer.
* @param title Window title
* @param width Window width
* @param height Window height
*/
RandomWalkerWindow(const std::string& title, int width, int height)
: ReWindow::RWindow(title, width, height) {}
: ReWindow::OpenGLWindow(title, width, height, 2, 1),
walker(std::make_unique<Walker>()),
trailBuffer{}, // Initialize trail buffer to white (1.0)
pushForce(3.0f) // Default push force
{}
void OnOpen() override {
if (!JGL::Init({WIDTH, HEIGHT}, 0, 0))
exit(0);
this->render_target = new RenderTarget({WIDTH, HEIGHT}, Colors::White);
}
/**
* @brief Called every frame to update and render the walker with a fading trail.
*/
void OnRefresh(float elapsed) override {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Clear with white
glClear(GL_COLOR_BUFFER_BIT);
GLSwapBuffers();
// Handle user inputs
handleMouseInput();
handleKeyboardInput();
// Move the walker
walker->step();
JGL::Update({WIDTH, HEIGHT});
J2D::Begin(render_target, true);
// Update trail (fade effect)
fadeTrail();
// Render the updated trail
drawTrail();
// Update the trail buffer with the walkers current position
plotWalker();
J2D::End();
J2D::Begin(nullptr, true);
J2D::DrawRenderTarget(render_target, {0, 0});
J2D::DrawString(Colors::Black, "Framerate: " + std::to_string((int) (1.f / delta_time)), 0, 0, 1, 16);
J2D::End();
// Swap buffers to display the frame
SwapBuffers();
}
private:
std::unique_ptr<Walker> walker;
std::vector<std::pair<Vector2, float>> trailBuffer{}; // Stores grayscale intensity of pixels (1.0 = white, 0.0 = black)
RenderTarget* render_target = nullptr;
float pushForce; // Variable push force that can be adjusted in real time
/**
* @brief Handles mouse input to push the walker away.
*/
void handleMouseInput() {
auto mousePos = GetMouseCoordinates();
if (IsMouseButtonDown(MouseButtons::Left)) {
walker->pushAway(mousePos.x, mousePos.y, pushForce);
}
}
/**
* @brief Handles keyboard input to reset the walker and adjust push force.
*/
void handleKeyboardInput() {
if (IsKeyDown(Keys::Space)) {
walker->resetPosition();
}
if (IsKeyDown(Keys::Escape)) {
Close();
}
// Adjust push force using number keys 1-5
if (IsKeyDown(Keys::One)) pushForce = 1.0f;
if (IsKeyDown(Keys::Two)) pushForce = 2.0f;
if (IsKeyDown(Keys::Three)) pushForce = 3.0f;
if (IsKeyDown(Keys::Four)) pushForce = 4.0f;
if (IsKeyDown(Keys::Five)) pushForce = 5.0f;
}
/**
* @brief Applies the fade effect to the trail buffer.
*/
void fadeTrail() {
// Fade out existing trail points
for (auto& trailPoint : trailBuffer)
trailPoint.second = std::max(trailPoint.second - FADE_SPEED, 0.0f);
trailBuffer.emplace_back(walker->position, 1.0f);
// Limit trail length
if (trailBuffer.size() > TRAIL_LENGTH)
trailBuffer.erase(trailBuffer.begin());
}
void drawTrail() {
for (const auto& trailPoint : trailBuffer)
J2D::DrawPoint({0, 0, 0, (uint8_t) (trailPoint.second * 255.0f)}, trailPoint.first, DOT_SIZE);
}
void plotWalker() {
J2D::DrawPoint(Colors::Black, walker->position, DOT_SIZE);
}
};
int main() {
auto window = std::make_unique<RandomWalkerWindow>("Random Walker with ReWindow", WIDTH, HEIGHT);
if (!window->Open())
return -1;
std::unique_ptr<RandomWalkerWindow> window =
std::make_unique<RandomWalkerWindow>("Random Walker with ReWindow", WIDTH, HEIGHT);
window->SetRenderer(RenderingAPI::OPENGL);
window->Open();
// Uncomment this to make things go super fast.
//window->SetVsyncEnabled(false);
while (!window->IsClosing()) {
window->ManagedRefresh();

View File

@@ -1,32 +1,30 @@
// simple test program to open a window with
// a blue background.
#include <rewindow/types/window.h>
#include <rewindow/logger/logger.h>
#include <ReWindow/types/Window.h>
#include <ReWindow/Logger.h>
#include <GL/gl.h>
#define WIDTH 800
#define HEIGHT 600
class RandomWalkerWindow : public ReWindow::RWindow {
class RandomWalkerWindow : public ReWindow::OpenGLWindow {
public:
RandomWalkerWindow(const std::string& title, int width, int height)
: ReWindow::RWindow(title, width, height) {}
: ReWindow::OpenGLWindow(title, width, height, 2, 1) {}
void OnRefresh(float elapsed) override {
glClearColor(0.0f, 0.0f, 1.0f, 1.0f); // Clear with blue
glClear(GL_COLOR_BUFFER_BIT);
GLSwapBuffers();
//glClearColor(0.0f, 0.0f, 1.0f, 1.0f); // Clear with blue
//glClear(GL_COLOR_BUFFER_BIT);
SwapBuffers();
}
};
int main() {
std::unique_ptr<RandomWalkerWindow> window =
std::make_unique<RandomWalkerWindow>("Random Walker with ReWindow", WIDTH, HEIGHT);
window->SetRenderer(RenderingAPI::OPENGL);
std::unique_ptr<RandomWalkerWindow> window =
std::make_unique<RandomWalkerWindow>("Random Walker with ReWindow", WIDTH, HEIGHT);
window->Open();
while (!window->IsClosing()) {