109 lines
2.6 KiB
C++
109 lines
2.6 KiB
C++
#pragma once
|
|
|
|
#include "dvr_triangle.h"
|
|
#include "math/dvc_vector4.h"
|
|
|
|
class Canvas
|
|
{
|
|
public:
|
|
struct Pixel
|
|
{
|
|
davinci::fVector3 color;
|
|
float alpha;
|
|
uint32_t mask;
|
|
int32_t fragementID;
|
|
};
|
|
typedef std::vector<Pixel> PixelArray;
|
|
|
|
struct Fragement
|
|
{
|
|
int32_t id;
|
|
davinci::fVector3 color;
|
|
uint32_t mask;
|
|
int32_t next;
|
|
};
|
|
typedef std::vector<Fragement> FragementArray;
|
|
|
|
public:
|
|
int32_t width() const { return m_width; }
|
|
int32_t height() const { return m_height; }
|
|
const Pixel& pixel(int32_t x, int32_t y) const
|
|
{
|
|
return m_pixels[y * m_width + x];
|
|
}
|
|
|
|
void reset(int32_t width, int32_t height);
|
|
void update(davinci::AntiAliasingTech aaTech, const TriangleArray& riangleArray, const Triangle* pActionTriangle = nullptr);
|
|
|
|
private:
|
|
void _insertTriangle(const Triangle& triangle);
|
|
void _update_without_AA();
|
|
|
|
template<int32_t kSampleSize>
|
|
void _update_with_AA()
|
|
{
|
|
for (size_t i = 0; i < m_pixels.size(); i++)
|
|
{
|
|
Pixel& pixel = m_pixels[i];
|
|
if (pixel.fragementID < 0) continue;
|
|
|
|
FragementArray pixelFragements;
|
|
int32_t fragementID = pixel.fragementID;
|
|
while (fragementID >= 0 && fragementID < m_fragementArray.size())
|
|
{
|
|
const Fragement& fragement = m_fragementArray[fragementID];
|
|
pixelFragements.insert(pixelFragements.begin(), fragement);
|
|
fragementID = fragement.next;
|
|
}
|
|
|
|
if (pixelFragements.size() == 0) continue;
|
|
else if (pixelFragements.size() == 1)
|
|
{
|
|
const Fragement& fragement = pixelFragements[0];
|
|
pixel.mask = fragement.mask;
|
|
pixel.color = fragement.color;
|
|
pixel.alpha = davinci::MathUtil::popcount((uint16_t)(fragement.mask)) / (float32_t)kSampleSize;
|
|
}
|
|
else
|
|
{
|
|
std::array<int32_t, kSampleSize> samples;
|
|
samples.fill(-1);
|
|
for (size_t j = 0; j < pixelFragements.size(); j++)
|
|
{
|
|
const Fragement& fragement = pixelFragements[j];
|
|
for (int32_t k = 0; k < kSampleSize; k++)
|
|
{
|
|
if ((fragement.mask & (1 << k)) != 0)
|
|
{
|
|
samples[k] = fragement.id;
|
|
}
|
|
}
|
|
}
|
|
|
|
pixel.mask = 0;
|
|
int32_t bitCounts = 0;
|
|
for (int32_t k = 0; k < kSampleSize; k++)
|
|
{
|
|
int32_t fragementID = samples[k];
|
|
if (fragementID < 0 || fragementID>m_fragementArray.size()) continue;
|
|
|
|
const Fragement& fragement = m_fragementArray[fragementID];
|
|
pixel.mask |= (1 << k);
|
|
pixel.color += fragement.color;
|
|
bitCounts++;
|
|
}
|
|
if (bitCounts > 1) {
|
|
pixel.color /= (float32_t)bitCounts;
|
|
}
|
|
pixel.alpha = bitCounts / (float32_t)kSampleSize;
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
int32_t m_width;
|
|
int32_t m_height;
|
|
PixelArray m_pixels; // final pixels in the canvas
|
|
FragementArray m_fragementArray;
|
|
};
|