支持抗锯齿

This commit is contained in:
2025-08-23 12:19:28 +08:00
parent dd72a8e3fd
commit 1f7720d54e
23 changed files with 879 additions and 183 deletions
+108
View File
@@ -0,0 +1,108 @@
#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;
};