Skip to content

Commit

Permalink
Introduced the concept of layers and render strategy, to be able to u…
Browse files Browse the repository at this point in the history
…se both optimised C rendering and GPU accel rendering, depending on the HW used
  • Loading branch information
pzaino committed Feb 29, 2024
1 parent 75a32a5 commit 9764488
Show file tree
Hide file tree
Showing 6 changed files with 277 additions and 49 deletions.
54 changes: 35 additions & 19 deletions src/cpp/fb
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,48 @@
* please refer to the official license documentation.
*/

#include <vector>
#include <cstdint> // For standard integer types

#include "fb.hpp"
#include "layer.hpp" // Ensure this is included if not already included in fb.hpp

// Constructor
FrameBuffer::FrameBuffer(unsigned int width, unsigned int height, std::shared_ptr<RenderStrategy> strategy)
: width(width), height(height), renderStrategy(strategy) {}

FrameBuffer::FrameBuffer(pixel_t width, pixel_t height) :
width_(width), height_(height), buffer_(width * height) {} // Initialize the buffer with the given width and height
// Add a layer to the framebuffer
void FrameBuffer::addLayer(const Layer& layer) {
layers.push_back(layer);
// Assuming Layer copy constructor or assignment operator handles the strategy correctly
}

void FrameBuffer::setPixel(pixel_t x, pixel_t y, color_t color) {
// Set the pixel at the given coordinates to the specified color
pixel_t index = y * getWidth() + x;
buffer[index] = color;
// Remove a layer from the framebuffer by index
void FrameBuffer::removeLayer(size_t index) {
if (index < layers.size()) {
layers.erase(layers.begin() + index);
}
}

color_t FrameBuffer::getPixel(pixel_t x, pixel_t y) const {
// Get the color of the pixel at the given coordinates
pixel_t index = y * getWidth() + x;
return buffer[index];
// Accessor for layer by index
Layer& FrameBuffer::getLayer(size_t index) {
// Simple bounds checking, throw std::out_of_range if index is invalid
if (index >= layers.size()) {
throw std::out_of_range("Layer index is out of range.");
}
return layers[index];
}

int FrameBuffer::getWidth() const {
// Get the width of the frame buffer
return buffer.size() / getHeight();
// Set the render strategy for the framebuffer and all its layers
void FrameBuffer::setRenderStrategy(std::shared_ptr<RenderStrategy> strategy) {
renderStrategy = strategy;
// Update the render strategy for all existing layers
for (auto& layer : layers) {
layer.setRenderStrategy(renderStrategy);
}
}

int FrameBuffer::getHeight() const {
// Get the height of the frame buffer
return buffer.size() / getWidth();
// Placeholder for the actual implementation of merging all layers
void FrameBuffer::mergeLayers() {
// Implementation depends on how you want to combine the layers
// This could involve blending pixels from each layer based on their opacity,
// and visibility, or simply stacking them in order.
// For simplicity, we're not providing a specific implementation here.
}
103 changes: 103 additions & 0 deletions src/cpp/layer
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* This file is part of:
* MicroFB, a minimal framebuffer library for RISC OS
*
* Description:
* This project aims to provide a simple and efficient way to manage
* the framebuffer on RISC OS using C++11. It abstracts the direct
* interaction with the GraphicsV API, offering a higher-level
* interface for drawing operations and framebuffer manipulation.
*
* Author:
* Paolo Fabio Zaino, all rights reserved.
* Distributed under License:
* CDDL v1.1 (Common Development and Distribution License Version
* 1.1) The use of this project is subject to the terms of the
* CDDL v1.1. This project can be used and distributed according
* to the terms of this license. For details on the CDDL v1.1,
* please refer to the official license documentation.
*/

#include "layer.hpp"

// Constructor implementation
Layer::Layer(pixel_t width, pixel_t height, std::shared_ptr<RenderStrategy> strategy)
: width(width), height(height), opacity(1.0f), visible(true), currentRenderStrategy(strategy) {
pixels.resize(width * height, 0); // Initialize pixel buffer with default color (0)
}

// Destructor implementation
Layer::~Layer() {
// No manual resource management needed here due to use of smart pointers and vectors
}

// Clear the layer with a specific color
void Layer::clear(color_t color) {
std::fill(pixels.begin(), pixels.end(), color);
}

// Direct pixel manipulation
void Layer::setPixel(pixel_t x, pixel_t y, color_t color) {
if (x < width && y < height) {
pixels[y * width + x] = color;
}
}

// Draw a line (placeholder for actual line drawing algorithm, e.g., Bresenham's)
void Layer::drawLine(pixel_t x1, pixel_t y1, pixel_t x2, pixel_t y2, color_t color) {
// Implementation of a line drawing algorithm goes here
}

// Draw a rectangle (simple example)
void Layer::drawRect(pixel_t x, pixel_t y, pixel_t w, pixel_t h, color_t color) {
for (pixel_t i = x; i < x + w; ++i) {
for (pixel_t j = y; j < y + h; ++j) {
setPixel(i, j, color);
}
}
}

// Fill a rectangle
void Layer::fillRect(pixel_t x, pixel_t y, pixel_t w, pixel_t h, color_t color) {
drawRect(x, y, w, h, color); // For simplicity, just using drawRect here
}

// Draw a circle (placeholder)
void Layer::drawCircle(pixel_t x, pixel_t y, pixel_t r, color_t color) {
// Placeholder for circle drawing algorithm
}

// Fill a circle (placeholder)
void Layer::fillCircle(pixel_t x, pixel_t y, pixel_t r, color_t color) {
// Placeholder for filled circle algorithm
}

// Draw an ellipse (placeholder)
void Layer::drawEllipse(pixel_t x, pixel_t y, pixel_t rx, pixel_t ry, color_t color) {
// Placeholder for ellipse drawing algorithm
}

// Fill an ellipse (placeholder)
void Layer::fillEllipse(pixel_t x, pixel_t y, pixel_t rx, pixel_t ry, color_t color) {
// Placeholder for filled ellipse algorithm
}

// Draw a polygon (placeholder)
void Layer::drawPolygon(const std::vector<pixel_t>& points, color_t color) {
// Placeholder for polygon drawing algorithm
}

// Fill a polygon (placeholder)
void Layer::fillPolygon(const std::vector<pixel_t>& points, color_t color) {
// Placeholder for filled polygon algorithm
}

// Draw text (placeholder)
void Layer::drawText(pixel_t x, pixel_t y, const char* text, color_t color) {
// Placeholder for text drawing algorithm
}

// Draw an image (placeholder)
void Layer::drawImage(pixel_t x, pixel_t y, const Layer& image) {
// Placeholder for image drawing algorithm
}
Empty file added src/cpp/render_strategy
Empty file.
51 changes: 21 additions & 30 deletions src/hpp/fb
Original file line number Diff line number Diff line change
Expand Up @@ -22,45 +22,36 @@
#define FB_HPP

#include <vector>
#include <cstdint> // For standard integer types
#include <memory> // For std::shared_ptr

typedef uint32_t color_t; // 32-bit color
typedef uint32_t pixel_t; // 32-bit pixel
#include "layer.hpp"
#include "render_strategy.hpp"

class FrameBuffer {
public:
FrameBuffer(pixel_t width, pixel_t height); // Constructor
~FrameBuffer(); // Destructor for cleanup
private:
std::vector<Layer> layers; // Collection of layers
std::shared_ptr<RenderStrategy> renderStrategy; // Shared rendering strategy
unsigned int width, height; // Dimensions of the framebuffer

void initialize(const char* fbDevicePath); // Initialize framebuffer device
void close(); // Close framebuffer device
public:
// Constructor that initializes the framebuffer with dimensions and a rendering strategy
FrameBuffer(unsigned int width, unsigned int height, std::shared_ptr<RenderStrategy> strategy)

pixel_t getWidth() const; // Get the framebuffer's width
pixel_t getHeight() const; // Get the framebuffer's height
// Add a layer to the framebuffer
void addLayer(const Layer& layer);

void setPixel(pixel_t x, pixel_t y, color_t color); // Set a pixel's color
color_t getPixel(pixel_t x, pixel_t y) const; // Get a pixel's color
// Remove a layer from the framebuffer by index
void removeLayer(size_t index);

void clear(color_t color = 0); // Clear the framebuffer with a specific color
// Accessor for layer by index
Layer& getLayer(size_t index);

// Add methods for drawing shapes, images, etc.
void drawPoint(pixel_t x, pixel_t y, color_t color); // Draw a point
void drawLine(pixel_t x1, pixel_t y1, pixel_t x2, pixel_t y2, color_t color); // Draw a line
void drawRectangle(pixel_t x, pixel_t y, pixel_t width, pixel_t height, color_t color); // Draw a rectangle
void drawCircle(pixel_t x, pixel_t y, pixel_t radius, color_t color); // Draw a circle
void drawEllipse(pixel_t x, pixel_t y, pixel_t xRadius, pixel_t yRadius, color_t color); // Draw an ellipse
void drawTriangle(pixel_t x1, pixel_t y1, pixel_t x2, pixel_t y2, pixel_t x3, pixel_t y3, color_t color); // Draw a triangle
void drawPolygon(const std::vector<pixel_t>& xCoords, const std::vector<pixel_t>& yCoords, color_t color); // Draw a polygon
void drawImage(const std::vector<color_t>& image, pixel_t x, pixel_t y, pixel_t width, pixel_t height); // Draw an image
// Set the render strategy for the framebuffer and all its layers
void setRenderStrategy(std::shared_ptr<RenderStrategy> strategy);

// TODO: Add methods for drawing text, etc.
// Method to merge all layers - Placeholder for actual implementation
void mergeLayers();

// TODO: Add methods for handling input, etc.

private:
pixel_t width_, height_;
std::vector<color_t> buffer_; // 32 bits per pixel (e.g., 8 bits for RGBA channels)
int fbFd_; // File descriptor for the framebuffer device
};

#endif // FB_HPP
#endif // FB_HPP
63 changes: 63 additions & 0 deletions src/hpp/layer
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* This file is part of:
* MicroFB, a minimal framebuffer library for RISC OS
*
* Description:
* This project aims to provide a simple and efficient way to manage
* the framebuffer on RISC OS using C++11. It abstracts the direct
* interaction with the GraphicsV API, offering a higher-level
* interface for drawing operations and framebuffer manipulation.
*
* Author:
* Paolo Fabio Zaino, all rights reserved.
* Distributed under License:
* CDDL v1.1 (Common Development and Distribution License Version
* 1.1) The use of this project is subject to the terms of the
* CDDL v1.1. This project can be used and distributed according
* to the terms of this license. For details on the CDDL v1.1,
* please refer to the official license documentation.
*/

#ifndef LAYER_HPP
#define LAYER_HPP

#include <vector>
#include <cstdint>
#include <memory> // For std::shared_ptr

#include "render_strategy.hpp"

typedef uint32_t color_t; // 32-bit color
typedef uint32_t pixel_t; // 32-bit pixel, assuming it represents dimensions

class Layer {
private:
std::shared_ptr<RenderStrategy> currentRenderStrategy;

public:
std::vector<color_t> pixels; // Pixel data for this layer
float opacity; // Layer opacity
bool visible; // Layer visibility
pixel_t width, height; // Dimensions of the layer

// Constructor and destructor
Layer(pixel_t width, pixel_t height, std::shared_ptr<RenderStrategy> strategy);
~Layer();

// Drawing operations
void clear(color_t color); // Clear the layer with a specific color
void setPixel(pixel_t x, pixel_t y, color_t color); // Direct pixel manipulation
void drawLine(pixel_t x1, pixel_t y1, pixel_t x2, pixel_t y2, color_t color); // Draw a line
void drawRect(pixel_t x, pixel_t y, pixel_t w, pixel_t h, color_t color); // Draw a rectangle
void fillRect(pixel_t x, pixel_t y, pixel_t w, pixel_t h, color_t color); // Fill a rectangle
void drawCircle(pixel_t x, pixel_t y, pixel_t r, color_t color); // Draw a circle
void fillCircle(pixel_t x, pixel_t y, pixel_t r, color_t color); // Fill a circle
void drawEllipse(pixel_t x, pixel_t y, pixel_t rx, pixel_t ry, color_t color); // Draw an ellipse
void fillEllipse(pixel_t x, pixel_t y, pixel_t rx, pixel_t ry, color_t color); // Fill an ellipse
void drawPolygon(const std::vector<pixel_t>& points, color_t color); // Draw a polygon
void fillPolygon(const std::vector<pixel_t>& points, color_t color); // Fill a polygon
void drawText(pixel_t x, pixel_t y, const char* text, color_t color); // Draw text
void drawImage(pixel_t x, pixel_t y, const Layer& image); // Draw an image
};

#endif // LAYER_HPP
55 changes: 55 additions & 0 deletions src/hpp/render_strategy
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* This file is part of:
* MicroFB, a minimal framebuffer library for RISC OS
*
* Description:
* This project aims to provide a simple and efficient way to manage
* the framebuffer on RISC OS using C++11. It abstracts the direct
* interaction with the GraphicsV API, offering a higher-level
* interface for drawing operations and framebuffer manipulation.
*
* Author:
* Paolo Fabio Zaino, all rights reserved.
* Distributed under License:
* CDDL v1.1 (Common Development and Distribution License Version
* 1.1) The use of this project is subject to the terms of the
* CDDL v1.1. This project can be used and distributed according
* to the terms of this license. For details on the CDDL v1.1,
* please refer to the official license documentation.
*/

#ifndef RENDERSTRATEGY_HPP
#define RENDERSTRATEGY_HPP

#include <memory>
#include <vector>
#include <cstdint> // For pixel_t and color_t types

// Forward declaration of Layer to resolve circular dependency
class Layer;

typedef uint32_t color_t; // 32-bit color, assuming it represents ARGB or similar
typedef uint32_t pixel_t; // 32-bit pixel, for dimensions

class RenderStrategy {
public:
virtual ~RenderStrategy() {}

// Pure virtual functions for rendering operations
virtual void setPixel(Layer& layer, pixel_t x, pixel_t y, color_t color) = 0;
virtual void drawLine(Layer& layer, pixel_t x1, pixel_t y1, pixel_t x2, pixel_t y2, color_t color) = 0;
virtual void drawRect(Layer& layer, pixel_t x, pixel_t y, pixel_t w, pixel_t h, color_t color) = 0;
virtual void fillRect(Layer& layer, pixel_t x, pixel_t y, pixel_t w, pixel_t h, color_t color) = 0;
virtual void drawCircle(Layer& layer, pixel_t x, pixel_t y, pixel_t r, color_t color) = 0;
virtual void fillCircle(Layer& layer, pixel_t x, pixel_t y, pixel_t r, color_t color) = 0;
virtual void drawEllipse(Layer& layer, pixel_t x, pixel_t y, pixel_t rx, pixel_t ry, color_t color) = 0;
virtual void fillEllipse(Layer& layer, pixel_t x, pixel_t y, pixel_t rx, pixel_t ry, color_t color) = 0;
virtual void drawPolygon(Layer& layer, const std::vector<pixel_t>& points, color_t color) = 0;
virtual void fillPolygon(Layer& layer, const std::vector<pixel_t>& points, color_t color) = 0;
virtual void drawText(Layer& layer, pixel_t x, pixel_t y, const char* text, color_t color) = 0;
virtual void drawImage(Layer& layer, pixel_t x, pixel_t y, const Layer& image) = 0;

// Additional methods for setup, teardown, or state management can be added here
};

#endif // RENDERSTRATEGY_HPP

0 comments on commit 9764488

Please sign in to comment.