paysages3d/src/render/software/CanvasPixel.cpp

90 lines
2.4 KiB
C++
Raw Normal View History

#include "CanvasPixel.h"
2014-06-10 13:13:16 +00:00
#include <cstring>
CanvasPixel::CanvasPixel() {
2014-06-10 13:13:16 +00:00
count = 0;
2014-06-12 15:45:59 +00:00
composite = COLOR_BLACK;
2014-06-10 13:13:16 +00:00
}
const CanvasFragment *CanvasPixel::getFrontFragment() const {
if (count == 0) {
2014-06-10 13:13:16 +00:00
return NULL;
} else {
2014-06-10 13:13:16 +00:00
return fragments + (count - 1);
}
}
void CanvasPixel::reset() {
2014-06-10 13:13:16 +00:00
count = 0;
composite = COLOR_BLACK;
2014-06-10 13:13:16 +00:00
}
void CanvasPixel::pushFragment(const CanvasFragment &fragment) {
if (count == 0) {
2014-06-10 13:13:16 +00:00
fragments[0] = fragment;
count = 1;
} else {
if (fragments[0].getOpaque() and fragment.getZ() <= fragments[0].getZ()) {
2014-06-10 13:13:16 +00:00
// behind opaque fragment, don't bother
return;
}
// find expected position
int i = 0;
while (i < count and fragment.getZ() >= fragments[i].getZ()) {
2014-06-10 13:13:16 +00:00
i++;
}
if (i > 0 and fragments[i - 1].getZ() == fragment.getZ() and
fragments[i - 1].getClient() == fragment.getClient()) {
// Pixel already pushed by same client, don't do anything
return;
}
if (fragment.getOpaque()) {
2014-06-10 13:13:16 +00:00
// Discard fragments masked by the incoming opaque one
if (i < count) {
2014-06-10 13:13:16 +00:00
memmove(fragments + 1, fragments + i, sizeof(CanvasFragment) * (count - i));
count -= i;
} else {
2014-06-10 13:13:16 +00:00
count = 1;
}
fragments[0] = fragment;
} else {
// Transparent pixel
if (i < count) {
// Need to make room for the incoming fragment
if (count < MAX_FRAGMENTS_PER_PIXEL) {
memmove(fragments + i + 1, fragments + i, sizeof(CanvasFragment) * (count - i));
fragments[i] = fragment;
count++;
}
} else {
if (count == MAX_FRAGMENTS_PER_PIXEL) {
// Replace nearest fragment
fragments[count - 1] = fragment;
} else {
// Append
fragments[count] = fragment;
count++;
}
2014-06-10 13:13:16 +00:00
}
}
}
2014-06-12 15:45:59 +00:00
updateComposite();
}
void CanvasPixel::updateComposite() {
2014-06-12 15:45:59 +00:00
Color result(0.0, 0.0, 0.0, 1.0);
for (int i = 0; i < count; i++) {
2014-06-12 15:45:59 +00:00
result.mask(fragments[i].getColor());
}
composite = result;
}
2014-08-18 10:17:16 +00:00
void CanvasPixel::setComposite(const Color &color) {
2014-08-18 10:17:16 +00:00
composite = color;
}