支持抗锯齿
This commit is contained in:
@@ -14,13 +14,16 @@
|
||||
|
||||
#include <scene/dvc_scene.h>
|
||||
|
||||
int32_t g_screenWidth = 1024;
|
||||
int32_t g_screenHeight = 768;
|
||||
int32_t g_screenWidth = 2048;
|
||||
int32_t g_screenHeight = 1024;
|
||||
static SDL_Window* window = NULL;
|
||||
AdapterTexture g_adapterTexture;
|
||||
SDL_GLContext gl_context;
|
||||
davinci::RenderTarget g_renderTarget;
|
||||
davinci::AntiAliasingTech g_aaTech = davinci::AntiAliasingTech::AA_None;
|
||||
|
||||
int32_t g_canvasWidth = 1024;
|
||||
int32_t g_canvasHeight = 512;
|
||||
davinci::Scene g_scene;
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
@@ -99,7 +102,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[])
|
||||
|
||||
// init davinci
|
||||
g_scene.init();
|
||||
g_renderTarget.init(512, 256);
|
||||
g_renderTarget.init(g_canvasWidth, g_canvasHeight);
|
||||
g_adapterTexture.updateTexture();
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
@@ -153,7 +156,7 @@ SDL_AppResult SDL_AppIterate(void* appstate)
|
||||
|
||||
//draw render result
|
||||
g_adapterTexture.updateTexture(0, 0, g_renderTarget.getColorBuffer());
|
||||
g_adapterTexture.updateTexture(512, 0, g_renderTarget.getDepthBuffer());
|
||||
g_adapterTexture.updateTexture(g_canvasWidth, 0, g_renderTarget.getDepthBuffer());
|
||||
g_adapterTexture.draw();
|
||||
|
||||
//draw ui
|
||||
|
||||
@@ -21,6 +21,7 @@ SDL_Window* main_window;
|
||||
|
||||
extern davinci::Scene g_scene;
|
||||
extern davinci::RenderTarget g_renderTarget;
|
||||
extern davinci::AntiAliasingTech g_aaTech;
|
||||
|
||||
bool initMainUI(SDL_Window* window, SDL_GLContext gl_context, const char* glsl_version)
|
||||
{
|
||||
@@ -96,6 +97,8 @@ void drawMainUI()
|
||||
{
|
||||
davinci_utils::export_mesh_to_obj(g_scene);
|
||||
}
|
||||
const char* aaItem[] = { "None", "MSAA_2X2", "MSAA_4X4"};
|
||||
ImGui::Combo("AntiAliasing", (int*)(&g_aaTech), aaItem, IM_ARRAYSIZE(aaItem));
|
||||
if (ImGui::Button("Render"))
|
||||
{
|
||||
davinci::UniformBuffer uniformBuffer;
|
||||
@@ -112,7 +115,9 @@ void drawMainUI()
|
||||
queue.build(g_scene);
|
||||
|
||||
g_renderTarget.clear();
|
||||
queue.process(uniformBuffer, g_renderTarget);
|
||||
queue.process(g_aaTech, uniformBuffer, g_renderTarget);
|
||||
|
||||
davinci_utils::dump_render_target("d:\\rendertarget", g_renderTarget);
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ set(DV_CORE_PIPE_INCLUDE_FILES
|
||||
include/pipe/dvc_render_step_IA.h
|
||||
include/pipe/dvc_render_step_VS.h
|
||||
include/pipe/dvc_render_step_PS.h
|
||||
include/pipe/dvc_render_step_OM.h
|
||||
)
|
||||
source_group("include/pipe" FILES ${DV_CORE_PIPE_INCLUDE_FILES})
|
||||
|
||||
@@ -122,6 +123,7 @@ set(DV_CORE_PIPE_SOURCE_FILES
|
||||
source/pipe/dvc_render_step_IA.cpp
|
||||
source/pipe/dvc_render_step_VS.cpp
|
||||
source/pipe/dvc_render_step_PS.cpp
|
||||
source/pipe/dvc_render_step_OM.cpp
|
||||
)
|
||||
source_group("source/pipe" FILES ${DV_CORE_PIPE_SOURCE_FILES})
|
||||
|
||||
|
||||
@@ -102,4 +102,12 @@ enum PixelFormat
|
||||
PF_UINT8_RGBA,
|
||||
};
|
||||
|
||||
enum AntiAliasingTech
|
||||
{
|
||||
AA_None,
|
||||
|
||||
AA_MSAA_2X2,
|
||||
AA_MSAA_4X4,
|
||||
};
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
|
||||
@@ -17,9 +17,11 @@ public:
|
||||
RenderableConstPtr getRenderable(size_t index) const;
|
||||
|
||||
void build(const Scene& scene);
|
||||
void process(UniformBuffer& uniformBuffer, RenderTarget& renderTarget);
|
||||
|
||||
void process(AntiAliasingTech aaTech, UniformBuffer& uniformBuffer, RenderTarget& renderTarget);
|
||||
|
||||
protected:
|
||||
AntiAliasingTech m_aaTech;
|
||||
std::vector<RenderableConstPtr> m_queue;
|
||||
|
||||
public:
|
||||
|
||||
@@ -23,11 +23,8 @@ public:
|
||||
|
||||
public:
|
||||
void process(const RenderQueue& renderQueue);
|
||||
const NodeArray& getNodes(void) const {
|
||||
return m_nodes;
|
||||
}
|
||||
|
||||
protected:
|
||||
public:
|
||||
NodeArray m_nodes;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include "dvc_config.h"
|
||||
#include "dvc_render_step_PS.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
class OutputMergerStep
|
||||
{
|
||||
public:
|
||||
void process(const PixelShaderStep::StartOffsetArray& startOffsetArray, const PixelShaderStep::FragementArray& fragementArray,
|
||||
AntiAliasingTech aaTech, RenderTarget& renderTarget);
|
||||
|
||||
private:
|
||||
void mergeFragement_without_AA(int32_t x, int32_t y,
|
||||
const std::multimap<float32_t, int32_t>& fragementArrayMap,
|
||||
const PixelShaderStep::FragementArray& fragementArray, RenderTarget& renderTarget);
|
||||
|
||||
template<int32_t kSampleSize, uint32_t kSampleMask>
|
||||
void mergeFragement_with_AA(int32_t x, int32_t y,
|
||||
const std::multimap<float32_t, int32_t>& fragementArrayMap,
|
||||
const PixelShaderStep::FragementArray& fragementArray, RenderTarget& renderTarget);
|
||||
};
|
||||
|
||||
template<int32_t kSampleSize, uint32_t kSampleMask>
|
||||
void OutputMergerStep::mergeFragement_with_AA(int32_t x, int32_t y, const std::multimap<float32_t, int32_t>& fragementArrayMap,
|
||||
const PixelShaderStep::FragementArray& fragementArray, RenderTarget& renderTarget)
|
||||
{
|
||||
if (fragementArrayMap.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (fragementArrayMap.size() == 1)
|
||||
{
|
||||
const PixelShaderStep::Fragement& fragement = fragementArray[fragementArrayMap.begin()->second];
|
||||
|
||||
fVector4 finalColor = fragement.color;
|
||||
finalColor.w = MathUtil::popcount((uint16_t)(fragement.mask & kSampleMask)) / (float32_t)kSampleSize;
|
||||
|
||||
renderTarget.setPixel(x, y, finalColor, fragement.depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::array<int32_t, kSampleSize> samples;
|
||||
samples.fill(-1);
|
||||
|
||||
float finalDepth = 0;
|
||||
std::multimap<float32_t, int32_t>::const_iterator it, end = fragementArrayMap.end();
|
||||
for (it = fragementArrayMap.begin(); it != end; ++it)
|
||||
{
|
||||
const PixelShaderStep::Fragement& fragement = fragementArray[it->second];
|
||||
for (int32_t k = 0; k < kSampleSize; k++)
|
||||
{
|
||||
if ((fragement.mask & (1 << k)) != 0)
|
||||
{
|
||||
samples[k] = it->second;
|
||||
}
|
||||
}
|
||||
finalDepth = fragement.depth;
|
||||
}
|
||||
|
||||
fVector3 finalColor(0.f, 0.f, 0.f);
|
||||
int32_t bitCounts = 0;
|
||||
for (int32_t k = 0; k < kSampleSize; k++)
|
||||
{
|
||||
int32_t fragementID = samples[k];
|
||||
if (fragementID < 0 || fragementID >= fragementArray.size()) continue;
|
||||
|
||||
const PixelShaderStep::Fragement& fragement = fragementArray[fragementID];
|
||||
finalColor += fragement.color.xyz();
|
||||
bitCounts++;
|
||||
}
|
||||
|
||||
if (bitCounts == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (bitCounts > 1)
|
||||
{
|
||||
finalColor /= (float32_t)bitCounts;
|
||||
}
|
||||
float32_t finalAlpha = bitCounts / (float32_t)kSampleSize;
|
||||
renderTarget.setPixel(x, y, fVector4(finalColor, finalAlpha), finalDepth);
|
||||
}
|
||||
}
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
@@ -8,8 +8,23 @@ DV_CORE_BEGIN_NAMESPACE
|
||||
class PixelShaderStep
|
||||
{
|
||||
public:
|
||||
void process(const VertexShaderStep::NodeArray& vsNodeArray, RenderTarget& renderTarget);
|
||||
struct Fragement
|
||||
{
|
||||
float32_t depth;
|
||||
fVector4 color;
|
||||
uint32_t mask;
|
||||
int32_t next;
|
||||
};
|
||||
|
||||
typedef std::vector<int32_t> StartOffsetArray;
|
||||
typedef std::vector<Fragement> FragementArray;
|
||||
|
||||
public:
|
||||
void process(const VertexShaderStep::NodeArray& vsNodeArray, AntiAliasingTech aaTech, int32_t canvasWidth, int32_t canvasHeight);
|
||||
|
||||
public:
|
||||
StartOffsetArray m_startOffsetArray;
|
||||
FragementArray m_fragementArray;
|
||||
};
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
|
||||
@@ -20,15 +20,10 @@ public:
|
||||
};
|
||||
typedef std::vector<Node> NodeArray;
|
||||
|
||||
public:
|
||||
const NodeArray& getNodes() const {
|
||||
return m_nodes;
|
||||
}
|
||||
|
||||
public:
|
||||
void process(UniformBuffer& uniformBuffer, const InputAssemberStep::NodeArray& assembedNodeArray);
|
||||
|
||||
protected:
|
||||
public:
|
||||
NodeArray m_nodes;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@ class DV_CORE_API Rasterizer
|
||||
{
|
||||
//Draw Triangle with Larrabee
|
||||
public:
|
||||
typedef std::function<void(const std::pair<int32_t, int32_t>& pos, const fVector3& percent)> DrawTriangleCallback;
|
||||
typedef std::function<
|
||||
void(const std::pair<int32_t, int32_t>& pos, const fVector3& percent, uint32_t mask)
|
||||
> DrawTriangleCallback;
|
||||
|
||||
struct DebugParam
|
||||
{
|
||||
@@ -27,9 +29,10 @@ public:
|
||||
};
|
||||
|
||||
//Larrabee algorithm
|
||||
static void drawTriangleLarrabee(int32_t canvasWidth, int32_t canvasHeight,
|
||||
static void drawTriangleLarrabee(AntiAliasingTech aaTech, int32_t canvasWidth, int32_t canvasHeight,
|
||||
const fVector2& v0, const fVector2& v1, const fVector2& v2,
|
||||
DrawTriangleCallback callback, bool ccw=true, const DebugParam* debugParam=nullptr);
|
||||
DrawTriangleCallback callback, bool ccw=true,
|
||||
const DebugParam* debugParam=nullptr);
|
||||
|
||||
public:
|
||||
//BoundingBox algorithm
|
||||
|
||||
@@ -16,7 +16,7 @@ void RenderTarget::init(int32_t width, int32_t height)
|
||||
|
||||
void RenderTarget::clear()
|
||||
{
|
||||
m_colorBuffer.clear(fVector4::BLACK);
|
||||
m_colorBuffer.clear(fVector4(0.f, 0.f, 0.f, 0.f));
|
||||
m_depthBuffer.clear(std::numeric_limits<float32_t>::max());
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ void RenderTarget::setPixel(int32_t x, int32_t y, const fVector4& color, float32
|
||||
if (x < 0 || x >= m_width || y < 0 || y >= m_height) return;
|
||||
|
||||
if (depth > m_depthBuffer.getPixel(x, y)) {
|
||||
return;
|
||||
// return;
|
||||
}
|
||||
m_colorBuffer.setPixel(x, y, color);
|
||||
m_depthBuffer.setPixel(x, y, depth);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "pipe/dvc_render_step_IA.h"
|
||||
#include "pipe/dvc_render_step_VS.h"
|
||||
#include "pipe/dvc_render_step_PS.h"
|
||||
#include "pipe/dvc_render_step_OM.h"
|
||||
#include "scene/component/dvc_camera_component.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
@@ -38,19 +39,25 @@ void RenderQueue::build(const Scene& scene)
|
||||
scene.getRootSceneNode()->buildRenderQueue(fMatrix4::IDENTITY, *this);
|
||||
}
|
||||
|
||||
void RenderQueue::process(UniformBuffer& uniformBuffer, RenderTarget& renderTarget)
|
||||
void RenderQueue::process(AntiAliasingTech aaTech, UniformBuffer& uniformBuffer, RenderTarget& renderTarget)
|
||||
{
|
||||
m_aaTech = aaTech;
|
||||
|
||||
//Assembere input
|
||||
InputAssemberStep IA;
|
||||
IA.process(*this);
|
||||
|
||||
//Vertex shader
|
||||
VertexShaderStep VS;
|
||||
VS.process(uniformBuffer, IA.getNodes());
|
||||
VS.process(uniformBuffer, IA.m_nodes);
|
||||
|
||||
//Pixel shader
|
||||
PixelShaderStep PS;
|
||||
PS.process(VS.getNodes(), renderTarget);
|
||||
PS.process(VS.m_nodes, m_aaTech, renderTarget.getWidth(), renderTarget.getHeight());
|
||||
|
||||
//Output Merge
|
||||
OutputMergerStep OM;
|
||||
OM.process(PS.m_startOffsetArray, PS.m_fragementArray, m_aaTech, renderTarget);
|
||||
}
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "pipe/dvc_render_step_OM.h"
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
void OutputMergerStep::process(const PixelShaderStep::StartOffsetArray& startOffsetArray, const PixelShaderStep::FragementArray& fragementArray,
|
||||
AntiAliasingTech aaTech, RenderTarget& renderTarget)
|
||||
{
|
||||
int32_t canvasWidth = renderTarget.getWidth();
|
||||
int32_t canvasHeight = renderTarget.getHeight();
|
||||
|
||||
for (int32_t y = 0; y < canvasHeight; y++)
|
||||
{
|
||||
for (int32_t x = 0; x < canvasWidth; x++)
|
||||
{
|
||||
int32_t fragementID = startOffsetArray[y * canvasWidth + x];
|
||||
std::multimap<float32_t, int32_t> fragementArrayMap;
|
||||
|
||||
while (fragementID >=0 && fragementID < (int32_t)fragementArray.size())
|
||||
{
|
||||
const PixelShaderStep::Fragement& fragement = fragementArray[fragementID];
|
||||
fragementArrayMap.insert(std::make_pair(-fragement.depth, fragementID));
|
||||
fragementID = fragement.next;
|
||||
}
|
||||
|
||||
if (aaTech == AntiAliasingTech::AA_None)
|
||||
{
|
||||
mergeFragement_without_AA(x, y, fragementArrayMap, fragementArray, renderTarget);
|
||||
}
|
||||
else if (aaTech == AntiAliasingTech::AA_MSAA_2X2)
|
||||
{
|
||||
mergeFragement_with_AA<4, 0xF>(x, y, fragementArrayMap, fragementArray, renderTarget);
|
||||
}
|
||||
else if (aaTech == AntiAliasingTech::AA_MSAA_4X4)
|
||||
{
|
||||
mergeFragement_with_AA<16, 0xFFFF>(x, y, fragementArrayMap, fragementArray, renderTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OutputMergerStep::mergeFragement_without_AA(int32_t x, int32_t y, const std::multimap<float32_t, int32_t>& fragementArrayMap,
|
||||
const PixelShaderStep::FragementArray& fragementArray, RenderTarget& renderTarget)
|
||||
{
|
||||
if (fragementArrayMap.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const PixelShaderStep::Fragement& firstFragement = fragementArray[fragementArrayMap.rbegin()->second];
|
||||
renderTarget.setPixel(x, y, firstFragement.color, firstFragement.depth);
|
||||
}
|
||||
|
||||
DV_CORE_END_NAMESPACE
|
||||
|
||||
@@ -6,17 +6,16 @@
|
||||
|
||||
DV_CORE_BEGIN_NAMESPACE
|
||||
|
||||
void PixelShaderStep::process(const VertexShaderStep::NodeArray& vsNodeArray, RenderTarget& renderTarget)
|
||||
void PixelShaderStep::process(const VertexShaderStep::NodeArray& vsNodeArray, AntiAliasingTech aaTech, int32_t canvasWidth, int32_t canvasHeight)
|
||||
{
|
||||
ShaderFileInterface* shaderInterface = davinci::LoadShaderFile("TestShader.dll");
|
||||
PixelShaderInterface* pixelShader = shaderInterface->getPixelShader("xxx");
|
||||
|
||||
int32_t targetWidth = renderTarget.getWidth();
|
||||
int32_t targetHeight = renderTarget.getHeight();
|
||||
|
||||
fMatrix4 view_trans =
|
||||
fMatrix4::makeTrans(targetWidth / 2.f, targetHeight / 2.f, 0.f) *
|
||||
fMatrix4::makeScale(targetWidth / 2.f, targetHeight / 2.f, 1.f);
|
||||
fMatrix4::makeTrans(canvasWidth / 2.f, canvasHeight / 2.f, 0.f) *
|
||||
fMatrix4::makeScale(canvasWidth / 2.f, canvasHeight / 2.f, 1.f);
|
||||
|
||||
m_startOffsetArray.resize(canvasWidth* canvasHeight, -1);
|
||||
|
||||
VertexShaderStep::NodeArray::const_iterator it, end = vsNodeArray.end();
|
||||
for (it = vsNodeArray.begin(); it != end; ++it)
|
||||
@@ -39,9 +38,10 @@ void PixelShaderStep::process(const VertexShaderStep::NodeArray& vsNodeArray, Re
|
||||
std::vector<float32_t> invZ = { node.invZ[i + 0], node.invZ[i + 1], node.invZ[i + 2] };
|
||||
std::vector<float32_t> vertexDepth = { node.depth[i+0], node.depth[i + 1], node.depth[i + 2]};
|
||||
|
||||
Rasterizer::drawTriangleLarrabee(targetWidth, targetHeight, pos0.xy(), pos1.xy(), pos2.xy(),
|
||||
[pixelShader, vertex0, vertex1, vertex2, invZ, vertexDepth, &node, &renderTarget]
|
||||
(const std::pair<int32_t, int32_t>& dot, const fVector3& percent)
|
||||
Rasterizer::drawTriangleLarrabee(aaTech,
|
||||
canvasWidth, canvasHeight, pos0.xy(), pos1.xy(), pos2.xy(),
|
||||
[this, canvasWidth, pixelShader, vertex0, vertex1, vertex2, invZ, vertexDepth, &node]
|
||||
(const std::pair<int32_t, int32_t>& dot, const fVector3& percent, uint32_t mask)
|
||||
{
|
||||
fVector3 percentCorrected(percent);
|
||||
|
||||
@@ -65,7 +65,16 @@ void PixelShaderStep::process(const VertexShaderStep::NodeArray& vsNodeArray, Re
|
||||
|
||||
int32_t x = dot.first;
|
||||
int32_t y = dot.second;
|
||||
renderTarget.setPixel(x, y, color, depth);
|
||||
int32_t currentOffset = m_startOffsetArray[x + y * canvasWidth];
|
||||
|
||||
m_startOffsetArray[x + y * canvasWidth] = (int32_t)(m_fragementArray.size());
|
||||
|
||||
Fragement newFragment;
|
||||
newFragment.color = color;
|
||||
newFragment.depth = depth;
|
||||
newFragment.mask = mask;
|
||||
newFragment.next = currentOffset;
|
||||
this->m_fragementArray.push_back(newFragment);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,22 +20,27 @@ inline bool operator==(const bool3_t& arr, bool value)
|
||||
|
||||
struct DrawTriangleParam
|
||||
{
|
||||
bool ccw;
|
||||
fVector2 verts[3];
|
||||
float32_t bbox_min_x;
|
||||
float32_t bbox_max_x;
|
||||
float32_t bbox_min_y;
|
||||
float32_t bbox_max_y;
|
||||
bool3_t tlBorder;
|
||||
float32_t area;
|
||||
iFloat3 edgesDX, edgesDY;
|
||||
iFloat3 halfEdge;
|
||||
AntiAliasingTech aaTech;
|
||||
bool ccw;
|
||||
fVector2 verts[3];
|
||||
float32_t bbox_min_x;
|
||||
float32_t bbox_max_x;
|
||||
float32_t bbox_min_y;
|
||||
float32_t bbox_max_y;
|
||||
bool3_t tlBorder;
|
||||
float32_t area;
|
||||
iFloat3 edgesDX, edgesDY;
|
||||
|
||||
iFloat3 halfEdge;
|
||||
iFloat3 quaterEdge;
|
||||
iFloat3 oneEighthEdge;
|
||||
|
||||
Rasterizer::DebugParam debugParam;
|
||||
};
|
||||
|
||||
enum { MIN_TILE_WIDTH_IN_PIXELS = 64 };
|
||||
|
||||
void _fillPixel(const DrawTriangleParam& param, int32_t xLB, int32_t yLB, Rasterizer::DrawTriangleCallback callback)
|
||||
void _fillPixel(const DrawTriangleParam& param, int32_t xLB, int32_t yLB, uint32_t mask, Rasterizer::DrawTriangleCallback callback)
|
||||
{
|
||||
fVector2 pixel(xLB + 0.5f, yLB + 0.5f);
|
||||
const fVector2 v0(param.verts[0]), v1(param.verts[1]), v2(param.verts[2]);
|
||||
@@ -46,42 +51,140 @@ void _fillPixel(const DrawTriangleParam& param, int32_t xLB, int32_t yLB, Raster
|
||||
|
||||
fVector3 t = fVector3(w0 / param.area, (param.ccw ? w1 : w2) / param.area, (param.ccw ? w2 : w1) / param.area);
|
||||
|
||||
callback(std::make_pair(xLB, yLB), t);
|
||||
callback(std::make_pair(xLB, yLB), t, mask);
|
||||
}
|
||||
|
||||
void _fillTile(const DrawTriangleParam& param, int32_t currentTileSize,
|
||||
int32_t xLB, int32_t yLB, Rasterizer::DrawTriangleCallback callback)
|
||||
{
|
||||
if (currentTileSize == 1)
|
||||
{
|
||||
_fillPixel(param, xLB, yLB, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t yIndex = yLB; yIndex < yLB + currentTileSize; yIndex++)
|
||||
{
|
||||
for (int32_t xIndex = xLB; xIndex < xLB + currentTileSize; xIndex++)
|
||||
{
|
||||
_fillPixel(param, xIndex, yIndex, callback);
|
||||
_fillPixel(param, xIndex, yIndex, ~0, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _drawPixel(DrawTriangleParam& param,
|
||||
void _drawPixel_without_AA(DrawTriangleParam& param,
|
||||
int32_t xLB, int32_t yLB, const iFloat3& edgesLB, const bool3_t& intersectant,
|
||||
Rasterizer::DrawTriangleCallback callback)
|
||||
{
|
||||
iFloat3 centerEdges(edgesLB);
|
||||
centerEdges.add(param.halfEdge);
|
||||
|
||||
bool insideTriangle =
|
||||
bool insideTriangle =
|
||||
(centerEdges.x > 0 || (param.tlBorder[0] && centerEdges.x == 0)) &&
|
||||
(centerEdges.y > 0 || (param.tlBorder[1] && centerEdges.y == 0)) &&
|
||||
(centerEdges.z > 0 || (param.tlBorder[2] && centerEdges.z == 0));
|
||||
|
||||
if (insideTriangle)
|
||||
{
|
||||
_fillPixel(param, xLB, yLB, callback);
|
||||
_fillPixel(param, xLB, yLB, ~0, callback);
|
||||
}
|
||||
}
|
||||
|
||||
void _drawPixel_with_MSAA2X2(DrawTriangleParam& param,
|
||||
int32_t x, int32_t y, const iFloat3& edgesLB, const bool3_t& intersectant,
|
||||
Rasterizer::DrawTriangleCallback callback)
|
||||
{
|
||||
// 2x2 MSAA;
|
||||
iFloat3 sampleEdgesDX(param.edgesDX);
|
||||
sampleEdgesDX.mul(iFloat::kHalf);
|
||||
|
||||
iFloat3 sampleEdgesDY(param.edgesDY);
|
||||
sampleEdgesDY.mul(iFloat::kHalf);
|
||||
|
||||
iFloat3 firstSampleEdges(edgesLB);
|
||||
firstSampleEdges.add(param.quaterEdge); // 0.25f
|
||||
|
||||
iFloat3 rowEdges(firstSampleEdges);
|
||||
|
||||
uint32_t mask = 0;
|
||||
for (int32_t yIndex = 0; yIndex < 2; yIndex++)
|
||||
{
|
||||
iFloat3 sampleEdges(rowEdges);
|
||||
|
||||
for (int32_t xIndex = 0; xIndex < 2; xIndex++)
|
||||
{
|
||||
bool sampleInsideTriangle =
|
||||
(sampleEdges.x > 0 || (param.tlBorder[0] && sampleEdges.x == 0)) &&
|
||||
(sampleEdges.y > 0 || (param.tlBorder[1] && sampleEdges.y == 0)) &&
|
||||
(sampleEdges.z > 0 || (param.tlBorder[2] && sampleEdges.z == 0));
|
||||
|
||||
if (sampleInsideTriangle)
|
||||
{
|
||||
mask |= (1 << (yIndex * 2 + xIndex));
|
||||
}
|
||||
|
||||
sampleEdges.sub(sampleEdgesDY);
|
||||
}
|
||||
|
||||
rowEdges.add(sampleEdgesDX);
|
||||
}
|
||||
|
||||
_fillPixel(param, x, y, mask, callback);
|
||||
}
|
||||
|
||||
void _drawPixel_with_MSAA4X4(DrawTriangleParam& param,
|
||||
int32_t x, int32_t y, const iFloat3& edgesLB, const bool3_t& intersectant,
|
||||
Rasterizer::DrawTriangleCallback callback)
|
||||
{
|
||||
// 4x4 MSAA;
|
||||
iFloat3 sampleEdgesDX(param.edgesDX);
|
||||
sampleEdgesDX.mul(iFloat::kQuater);
|
||||
|
||||
iFloat3 sampleEdgesDY(param.edgesDY);
|
||||
sampleEdgesDY.mul(iFloat::kQuater);
|
||||
|
||||
iFloat3 firstSampleEdges(edgesLB);
|
||||
firstSampleEdges.add(param.oneEighthEdge); // 0.125f
|
||||
|
||||
iFloat3 rowEdges(firstSampleEdges);
|
||||
|
||||
uint32_t mask = 0;
|
||||
for (int32_t yIndex = 0; yIndex < 4; yIndex++)
|
||||
{
|
||||
iFloat3 sampleEdges(rowEdges);
|
||||
|
||||
for (int32_t xIndex = 0; xIndex < 4; xIndex++)
|
||||
{
|
||||
bool sampleInsideTriangle =
|
||||
(sampleEdges.x > 0 || (param.tlBorder[0] && sampleEdges.x == 0)) &&
|
||||
(sampleEdges.y > 0 || (param.tlBorder[1] && sampleEdges.y == 0)) &&
|
||||
(sampleEdges.z > 0 || (param.tlBorder[2] && sampleEdges.z == 0));
|
||||
|
||||
if (sampleInsideTriangle)
|
||||
{
|
||||
mask |= (1 << (yIndex * 4 + xIndex));
|
||||
}
|
||||
|
||||
sampleEdges.sub(sampleEdgesDY);
|
||||
}
|
||||
|
||||
rowEdges.add(sampleEdgesDX);
|
||||
}
|
||||
|
||||
_fillPixel(param, x, y, mask, callback);
|
||||
}
|
||||
|
||||
void _drawPixel(DrawTriangleParam& param,
|
||||
int32_t xLB, int32_t yLB, const iFloat3& edgesLB, const bool3_t& intersectant,
|
||||
Rasterizer::DrawTriangleCallback callback)
|
||||
{
|
||||
switch (param.aaTech)
|
||||
{
|
||||
case AntiAliasingTech::AA_MSAA_4X4:
|
||||
_drawPixel_with_MSAA4X4(param, xLB, yLB, edgesLB, intersectant, callback);
|
||||
break;
|
||||
|
||||
case AntiAliasingTech::AA_MSAA_2X2:
|
||||
_drawPixel_with_MSAA2X2(param, xLB, yLB, edgesLB, intersectant, callback);
|
||||
break;
|
||||
|
||||
case AntiAliasingTech::AA_None:
|
||||
default:
|
||||
_drawPixel_without_AA(param, xLB, yLB, edgesLB, intersectant, callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +301,7 @@ void _drawTriangle_Tile(DrawTriangleParam& param, int32_t currentTileSize,
|
||||
}
|
||||
}
|
||||
|
||||
void Rasterizer::drawTriangleLarrabee(int32_t canvasWidth, int32_t canvasHeight,
|
||||
void Rasterizer::drawTriangleLarrabee(AntiAliasingTech aaTech, int32_t canvasWidth, int32_t canvasHeight,
|
||||
const fVector2& v0, const fVector2& v1, const fVector2& v2,
|
||||
DrawTriangleCallback callback, bool ccw, const DebugParam* debugParam)
|
||||
{
|
||||
@@ -225,6 +328,7 @@ void Rasterizer::drawTriangleLarrabee(int32_t canvasWidth, int32_t canvasHeight,
|
||||
tileSize /= 4;
|
||||
|
||||
DrawTriangleParam param;
|
||||
param.aaTech = aaTech;
|
||||
int32_t widthInTiles = canvasWidth / tileSize;
|
||||
|
||||
//Whether the three input vertices are in the agreed clockwise order or not,
|
||||
@@ -285,7 +389,10 @@ void Rasterizer::drawTriangleLarrabee(int32_t canvasWidth, int32_t canvasHeight,
|
||||
size_t v_end = (v + 1) % 3;
|
||||
param.edgesDX[v] = vertices[v_end].x - vertices[v].x;
|
||||
param.edgesDY[v] = vertices[v_end].y - vertices[v].y;
|
||||
|
||||
param.halfEdge[v] = (param.edgesDX[v]- param.edgesDY[v]) * iFloat::kHalf;
|
||||
param.quaterEdge[v] = (param.edgesDX[v] - param.edgesDY[v]) * iFloat::kQuater;
|
||||
param.oneEighthEdge[v] = (param.edgesDX[v] - param.edgesDY[v]) * iFloat::kOneEighth;
|
||||
|
||||
tileEdgesDX[v] = param.edgesDX[v] * tileSize;
|
||||
tileEdgesDY[v] = param.edgesDY[v] * tileSize;
|
||||
@@ -374,8 +481,6 @@ void Rasterizer::drawTriangleLarrabee(int32_t canvasWidth, int32_t canvasHeight,
|
||||
}
|
||||
|
||||
iFloat3 rowEdges(edgesFirstLB);
|
||||
|
||||
int32_t tile_row_start = first_tile_y * tileSize + first_tile_x;
|
||||
int32_t yLB = first_tile_y * tileSize;
|
||||
|
||||
for (int32_t tile_y = first_tile_y; tile_y <= last_tile_y; tile_y++)
|
||||
@@ -384,7 +489,6 @@ void Rasterizer::drawTriangleLarrabee(int32_t canvasWidth, int32_t canvasHeight,
|
||||
iFloat3 tileEdgesReject(edgesReject);
|
||||
iFloat3 tileEdgesAccept(edgesAccept);
|
||||
|
||||
int32_t tile_i = tile_row_start;
|
||||
int32_t xLB = first_tile_x * tileSize;
|
||||
|
||||
for (int32_t tile_x = first_tile_x; tile_x <= last_tile_x; tile_x++)
|
||||
@@ -414,7 +518,6 @@ void Rasterizer::drawTriangleLarrabee(int32_t canvasWidth, int32_t canvasHeight,
|
||||
edgesTileLB.sub(tileEdgesDY);
|
||||
tileEdgesReject.sub(tileEdgesDY);
|
||||
tileEdgesAccept.sub(tileEdgesDY);
|
||||
tile_i++;
|
||||
xLB += tileSize;
|
||||
}
|
||||
|
||||
@@ -422,7 +525,6 @@ void Rasterizer::drawTriangleLarrabee(int32_t canvasWidth, int32_t canvasHeight,
|
||||
rowEdges.add(tileEdgesDX);
|
||||
edgesReject.add(tileEdgesDX);
|
||||
edgesAccept.add(tileEdgesDX);
|
||||
tile_row_start += widthInTiles;
|
||||
yLB += tileSize;
|
||||
}
|
||||
|
||||
@@ -505,7 +607,7 @@ void Rasterizer::drawTriangleBoundingBox(int32_t canvasWidth, int32_t canvasHeig
|
||||
|
||||
fVector3 t = fVector3(w0 / area, (ccw ? w1 : w2) / area, (ccw ? w2 : w1) / area);
|
||||
|
||||
callback(std::make_pair(x, y), t);
|
||||
callback(std::make_pair(x, y), t, ~0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
Reference in New Issue
Block a user