This commit is contained in:
2026-11-02 19:35:36 -05:00
parent a6103e453d
commit 7b32ad674e
52 changed files with 3285 additions and 1488 deletions
+71
View File
@@ -0,0 +1,71 @@
#ifndef TEXTURE_PAINTER_CLASS
#define TEXTURE_PAINTER_CLASS
#include <cmath>
#include <glm/glm.hpp>
#include "texture.h"
// The brush behind the texture drawer. Edits a Texture's pixels and uploads them.
class TexturePainter {
public:
glm::vec3 color = glm::vec3(0.0f);
int brushSize = 8; // radius in pixels of a 256 wide texture, so it looks the same on any size
// uv runs 0-1 from the top left of the image. Joins up with the last call until EndStroke.
void Stroke(Texture& texture, const glm::vec2& uv) {
const glm::vec2 point(uv.x * texture.width, (1.0f - uv.y) * texture.height);
const float radius = glm::max(1.0f, brushSize * texture.width / 256.0f);
if (!stroking) {
Stamp(texture, point, radius);
}
else {
// Fill the gap, the mouse can cross a lot of pixels in one frame
const int steps = (int)std::ceil(glm::length(point - lastPoint) / (radius * 0.5f));
for (int i = 1; i <= steps; i++)
Stamp(texture, glm::mix(lastPoint, point, (float)i / (float)steps), radius);
}
stroking = true;
lastPoint = point;
texture.Upload();
}
void EndStroke() {
stroking = false;
}
void Clear(Texture& texture) {
texture.pixels.assign(texture.pixels.size(), 255);
texture.Upload();
}
private:
bool stroking = false;
glm::vec2 lastPoint = glm::vec2(0.0f);
void Stamp(Texture& texture, const glm::vec2& center, float radius) {
const int minX = glm::max((int)(center.x - radius), 0);
const int maxX = glm::min((int)(center.x + radius), texture.width - 1);
const int minY = glm::max((int)(center.y - radius), 0);
const int maxY = glm::min((int)(center.y + radius), texture.height - 1);
for (int y = minY; y <= maxY; y++) {
for (int x = minX; x <= maxX; x++) {
const glm::vec2 offset = glm::vec2(x + 0.5f, y + 0.5f) - center;
if (glm::dot(offset, offset) > radius * radius)
continue;
unsigned char* pixel = &texture.pixels[((size_t)y * texture.width + x) * 4];
pixel[0] = (unsigned char)(color.r * 255.0f);
pixel[1] = (unsigned char)(color.g * 255.0f);
pixel[2] = (unsigned char)(color.b * 255.0f);
pixel[3] = 255;
}
}
}
};
#endif