forked from rich/ReWalker
added trail effect
This commit is contained in:
101
main.cpp
101
main.cpp
@@ -1,5 +1,5 @@
|
||||
// ReWalker
|
||||
// A random walker that moves around the screen
|
||||
// A random walker that moves around the screen with a fading trail.
|
||||
// Written using Redacted ReWindow https://git.redacted.cc/Redacted/ReWindow
|
||||
// Written by Rich
|
||||
// With help from (and thanks to) from Maxine, Josh and Bill
|
||||
@@ -11,14 +11,18 @@
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// 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.01f
|
||||
|
||||
// Enable debug mode (set to 0 to disable debug output)
|
||||
#define DEBUG 1
|
||||
#define DEBUG 0
|
||||
|
||||
/**
|
||||
* @brief Represents the walker that moves randomly on the screen.
|
||||
@@ -33,9 +37,6 @@ struct Walker {
|
||||
|
||||
/**
|
||||
* @brief Moves the walker one step in a random direction.
|
||||
*
|
||||
* Uses a random angle (0-360 degrees) to determine movement direction.
|
||||
* Ensures the walker stays within the screen bounds using std::clamp.
|
||||
*/
|
||||
void step() {
|
||||
float angle = static_cast<float>(rand()) / RAND_MAX * 360.0f;
|
||||
@@ -47,7 +48,6 @@ struct Walker {
|
||||
x = std::clamp(x + dx, 0.0f, static_cast<float>(WIDTH - 1));
|
||||
y = std::clamp(y + dy, 0.0f, static_cast<float>(HEIGHT - 1));
|
||||
|
||||
// Debugging: Print walker's position if debug mode is enabled
|
||||
#if DEBUG
|
||||
std::cout << "Walker Position: (" << x << ", " << y << ")\n";
|
||||
#endif
|
||||
@@ -60,19 +60,20 @@ struct Walker {
|
||||
class RandomWalkerWindow : public ReWindow::RWindow {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor initializes the window and walker.
|
||||
* @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), walker(std::make_unique<Walker>()) {}
|
||||
: ReWindow::RWindow(title, width, height),
|
||||
walker(std::make_unique<Walker>()),
|
||||
trailBuffer(WIDTH * HEIGHT, 1.0f) // Initialize trail buffer to white (1.0)
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief Called once when the window is opened.
|
||||
*
|
||||
* Configures OpenGL to use a 2D orthographic projection
|
||||
* so that pixel coordinates match OpenGL coordinates.
|
||||
* Configures OpenGL to use a 2D orthographic projection.
|
||||
*/
|
||||
void OnOpen() override {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
@@ -82,50 +83,74 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called every frame to update and render the walker.
|
||||
*
|
||||
* Clears the screen, moves the walker, draws it, and swaps buffers.
|
||||
* @param elapsed Time elapsed since the last frame (not currently used).
|
||||
* @brief Called every frame to update and render the walker with a fading trail.
|
||||
*/
|
||||
void OnRefresh(float elapsed) override {
|
||||
// Clear the screen to white each frame
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
// Clear the OpenGL buffer (not the trail buffer)
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Move the walker in a random direction
|
||||
// Update trail (fade effect)
|
||||
fadeTrail();
|
||||
|
||||
// Move the walker
|
||||
walker->step();
|
||||
|
||||
// Render the walker on the screen
|
||||
drawWalker();
|
||||
// Update the trail buffer with the walker's current position
|
||||
plotWalker();
|
||||
|
||||
// Render the updated trail
|
||||
drawTrail();
|
||||
|
||||
// Swap buffers to display the frame
|
||||
GLSwapBuffers();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Walker> walker; // Unique pointer to manage walker instance
|
||||
std::unique_ptr<Walker> walker;
|
||||
std::vector<float> trailBuffer; // Stores grayscale intensity of pixels (1.0 = white, 0.0 = black)
|
||||
|
||||
/**
|
||||
* @brief Draws the walker as a black square on the screen.
|
||||
*
|
||||
* Uses OpenGL `GL_QUADS` to draw a filled square at the walker’s position.
|
||||
* @brief Applies the fade effect to the trail buffer.
|
||||
* Each pixel brightness gradually increases toward 1.0 (white).
|
||||
*/
|
||||
void drawWalker() {
|
||||
float halfSize = DOT_SIZE / 2.0f;
|
||||
float left = walker->x - halfSize;
|
||||
float right = walker->x + halfSize;
|
||||
float top = walker->y - halfSize;
|
||||
float bottom = walker->y + halfSize;
|
||||
void fadeTrail() {
|
||||
for (auto& pixel : trailBuffer) {
|
||||
pixel = std::min(pixel + FADE_SPEED, 1.0f); // Ensure value does not exceed 1.0 (white)
|
||||
}
|
||||
}
|
||||
|
||||
glColor3f(0.0f, 0.0f, 0.0f); // Set color to black
|
||||
/**
|
||||
* @brief Plots the walker current position as a black dot in the trail buffer.
|
||||
*/
|
||||
void plotWalker() {
|
||||
int centerX = static_cast<int>(walker->x);
|
||||
int centerY = static_cast<int>(walker->y);
|
||||
int halfSize = DOT_SIZE / 2;
|
||||
|
||||
// Draw a filled square (dot) at the walker's position
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(left, top);
|
||||
glVertex2f(right, top);
|
||||
glVertex2f(right, bottom);
|
||||
glVertex2f(left, bottom);
|
||||
glEnd();
|
||||
for (int dy = -halfSize; dy <= halfSize; ++dy) {
|
||||
for (int dx = -halfSize; dx <= halfSize; ++dx) {
|
||||
int px = centerX + dx;
|
||||
int py = centerY + dy;
|
||||
|
||||
if (px >= 0 && px < WIDTH && py >= 0 && py < HEIGHT) {
|
||||
trailBuffer[py * WIDTH + px] = 0.0f; // Set to black (no fade)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Renders the trail buffer to the screen using OpenGL.
|
||||
*/
|
||||
void drawTrail() {
|
||||
// Convert float values (0.0-1.0) to grayscale (0-255) for rendering
|
||||
std::vector<uint8_t> grayscale(WIDTH * HEIGHT);
|
||||
for (size_t i = 0; i < trailBuffer.size(); ++i) {
|
||||
grayscale[i] = static_cast<uint8_t>(trailBuffer[i] * 255.0f);
|
||||
}
|
||||
|
||||
// Render grayscale buffer
|
||||
glDrawPixels(WIDTH, HEIGHT, GL_LUMINANCE, GL_UNSIGNED_BYTE, grayscale.data());
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user