I'm trying to create a simple painting application. And I was wondering about an efficient way to draw pixels on the screen.
I have a pixel struct:
struct Pixel {
unsigned char r, g, b, a;
};
And I have two methods for converting between pixel coordinates and normalized pixel coordinates. w
and h
are image width and height respectively.
int getPixelIndex(float2 norm, int w, int h) {
return (int)(norm.x*h)*w + norm.y*h;
}
float2 getPixelNormCoords(int index, int w, int h) {
float2 norm;
norm.x = (index % w) / (float)(w-1);
norm.y = (index / h) / (float)(h-1);
return norm;
}
Now if I want to draw a red pixel under the cursor I could do it like this:
int pixelIndex = getPixelIndex(cursorNorm.x, cursorNorm.y, w, h);
pixels[pixelIndex] = {255, 0, 0, 255};
However what if I want to fill more pixels around the cursor, to create different brushes. Say I want to create a square brush with a given offset d
. One hacky way to do this would be:
float delta = 10e-4;
for (float i = -d; i < d; i+=delta) {
for (float j = -d; j < d; j+=delta) {
int pixelIndex = getPixelIndex(cursorNorm.x+i, cursorNorm.y+j, w, h);
pixels[pixelIndex] = {255, 0, 0, 255};
}
}
Another way would be to iterate over each pixel:
for (int i = 0; i < size(pixels); i++) {
float2 norm = getPixelNormCoords(i, w, h);
if (fabs(norm.x-cursorNorm.x) < d && fabs(norm.y-cursorNorm.y) < d)
pixels[i] = {255, 0, 0, 255};
}
However this way seems to be extremely costly.
Are there more efficient and less hacky methods to accomplish what I'm trying to do?