#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 PixelArray; struct Fragement { int32_t id; davinci::fVector3 color; uint32_t mask; int32_t next; }; typedef std::vector 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 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 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; };