Reputation: 77
I'm generating textures for UI elements that have a single pixel outline on the edge of the texture.
The method of setting the color data in the texture is limited to passing a one dimensional array of color values.
These textures are 2D, so they are basically rectangles. I need to be able to identify when the current pixel is at an edge. This is how I currently do it:
Color[] colorData = new Color[width * height];
for (int p = 0; p < colorData.Length; p++) {
//Top
if (p < width - 1) {
colorData[p] = DefaultOutlineColor;
}
//Left
else if(p % width == 0) {
colorData[p] = DefaultOutlineColor;
}
//Right
else if(p % height == height - outlineWidth) {
colorData[p] = DefaultOutlineColor;
}
//Bottom
else if(p >= width * (height - outlineWidth)) {
colorData[p] = DefaultOutlineColor;
}
//Fill
else {
colorData[p] = DefaultBaseColor;
}
}
Some Modulo math and what not. The problem I am having is with the Right side of the Texture. More specifically calculating the right side edge. A picture is worth a thousand words:
I know it is just a miss calculation in the Right edge part. But I have no idea how to make it work. Any help would be highly appreciated.
EDIT: Figured it out. Here is the working code:
//Fill
for (int p = 0; p < colorData.Length; p++) {
colorData[p] = DefaultBaseColor;
}
//Top
for (int p = 0; width * outlineWidth > p; p++) {
colorData[p] = DefaultOutlineColor;
}
//Left and Right
for (int p = 1; height > p; p++) {
for (int i = 0; i < outlineWidth; i++) {
colorData[(p * width) + i] = DefaultOutlineColor; //Left
colorData[((p * width) - i) - 1] = DefaultOutlineColor; //Right
}
}
//Bottom
for (int p = width * height - (width * outlineWidth); colorData.Length > p; p++) {
colorData[p] = DefaultOutlineColor;
}
Upvotes: 2
Views: 104
Reputation: 91
In practice you're doing a one-pixel border - but you use outlineWidth
in your original code, so here's an alternative method that works fine for arbitrary border sizes.
for (int p = 0; p < colorData.length; p++) {
// retrieving the x/y coords isn't expensive if you do this only once
int x = p % height;
int y = p / height;
if (x < outlineSize || y < outlineSize || x >= width - outlineSize || y >= height - outlineSize) {
colorData[p] = DefaultOutlineColor;
}
}
Upvotes: 0
Reputation: 15172
Why not do it in three loops? One for the top, one for the left and right and then one for the bottom? That way you can skip all the items that don't need to be touched at all.
for(int ndx = 0; Width > ndx; ++ndx)
{
colorData[ndx] = DefaultOutlineColor;
}
for(int ndx = 1; Height > ndx; ++ndx)
{
colorDatandx * Widthp] = DefaultOutlineColor;
colorData[ndx*Width + Width] = DefaultOutlineColor;}
}
for(int ndx = Width * Height - Width; Length > ndx; ++ndx)
{
colorDatandxp] = DefaultOutlineColor;
}
Upvotes: 2
Reputation: 77
Using SoronelHaetir's method I figured it out. Had to edit the math a little bit. Here is the working code if anyone is interested:
for (int ndx = 0; width > ndx; ndx++) {
colorData[ndx] = DefaultOutlineColor;
}
for (int ndx = 1; height > ndx ; ndx++) {
colorData[ndx * width] = DefaultOutlineColor;
colorData[(ndx * width) - 1] = DefaultOutlineColor;
}
for (int ndx = width * height - width; colorData.Length > ndx; ndx++) {
colorData[ndx] = DefaultOutlineColor;
}
Upvotes: 1