You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
6.3 KiB
C++
182 lines
6.3 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
|
|
#ifndef CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H
|
|
#define CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H
|
|
#pragma once
|
|
|
|
class CSimpleTriangleRasterizer
|
|
{
|
|
public:
|
|
|
|
class IRasterizeSink
|
|
{
|
|
public:
|
|
|
|
//! is called once per triangel for the first possible visible line
|
|
//! /param iniStartY
|
|
virtual void Triangle([[maybe_unused]] const int iniStartY)
|
|
{
|
|
}
|
|
|
|
//! callback function
|
|
//! /param infXLeft included - not clipped against left and reight border
|
|
//! /param infXRight excluded - not clipped against left and reight border
|
|
//! /param iniXLeft included
|
|
//! /param iniXRight excluded
|
|
//! /param iniY
|
|
virtual void Line(const float infXLeft, const float infXRight,
|
|
const int iniXLeft, const int iniXRight, const int iniY) = 0;
|
|
};
|
|
|
|
typedef unsigned long DWORD;
|
|
|
|
// -----------------------------------------------------
|
|
|
|
//! implementation sink sample
|
|
class CDWORDFlatFill
|
|
: public IRasterizeSink
|
|
{
|
|
public:
|
|
|
|
//! constructor
|
|
CDWORDFlatFill(DWORD* inpBuffer, const DWORD indwPitchInPixels, DWORD indwValue)
|
|
{
|
|
m_dwValue = indwValue;
|
|
m_pBuffer = inpBuffer;
|
|
m_dwPitchInPixels = indwPitchInPixels;
|
|
}
|
|
|
|
virtual void Triangle(const int iniY)
|
|
{
|
|
m_pBufferLine = &m_pBuffer[iniY * m_dwPitchInPixels];
|
|
}
|
|
|
|
virtual void Line([[maybe_unused]] const float infXLeft, [[maybe_unused]] const float infXRight,
|
|
const int iniLeft, const int iniRight, [[maybe_unused]] const int iniY)
|
|
{
|
|
DWORD* mem = &m_pBufferLine[iniLeft];
|
|
|
|
for (int x = iniLeft; x < iniRight; x++)
|
|
{
|
|
*mem++ = m_dwValue;
|
|
}
|
|
|
|
m_pBufferLine += m_dwPitchInPixels;
|
|
}
|
|
|
|
private:
|
|
DWORD m_dwValue; //!< fill value
|
|
DWORD* m_pBufferLine; //!< to get rid of the multiplication per line
|
|
|
|
DWORD m_dwPitchInPixels; //!< in DWORDS, not in Bytes
|
|
DWORD* m_pBuffer; //!< pointer to the buffer
|
|
};
|
|
|
|
// -----------------------------------------------------
|
|
|
|
//! constructor
|
|
//! /param iniWidth excluded
|
|
//! /param iniHeight excluded
|
|
CSimpleTriangleRasterizer(const int iniWidth, const int iniHeight)
|
|
{
|
|
m_iMinX = 0;
|
|
m_iMinY = 0;
|
|
m_iMaxX = iniWidth - 1;
|
|
m_iMaxY = iniHeight - 1;
|
|
}
|
|
/*
|
|
//! constructor
|
|
//! /param iniMinX included
|
|
//! /param iniMinY included
|
|
//! /param iniMaxX included
|
|
//! /param iniMaxY included
|
|
CSimpleTriangleRasterizer( const int iniMinX, const int iniMinY, const int iniMaxX, const int iniMaxY )
|
|
{
|
|
m_iMinX=iniMinX;
|
|
m_iMinY=iniMinY;
|
|
m_iMaxX=iniMaxX;
|
|
m_iMaxY=iniMaxY;
|
|
}
|
|
*/
|
|
//! simple triangle filler with clipping (optimizable), not subpixel correct
|
|
//! /param pBuffer pointer o the color buffer
|
|
//! /param indwWidth width of the color buffer
|
|
//! /param indwHeight height of the color buffer
|
|
//! /param x array of the x coordiantes of the three vertices
|
|
//! /param y array of the x coordiantes of the three vertices
|
|
//! /param indwValue value of the triangle
|
|
void DWORDFlatFill(DWORD* inpBuffer, const DWORD indwPitchInPixels, float x[3], float y[3], DWORD indwValue, bool inbConservative)
|
|
{
|
|
CDWORDFlatFill pix(inpBuffer, indwPitchInPixels, indwValue);
|
|
|
|
if (inbConservative)
|
|
{
|
|
CallbackFillConservative(x, y, &pix);
|
|
}
|
|
else
|
|
{
|
|
CallbackFillSubpixelCorrect(x, y, &pix);
|
|
}
|
|
}
|
|
|
|
// Rectangle around triangle - more stable - use for debugging purpose
|
|
void CallbackFillRectConservative(float x[3], float y[3], IRasterizeSink * inpSink);
|
|
|
|
|
|
//! subpixel correct triangle filler (conservative or not conservative)
|
|
//! \param pBuffer pointe to the DWORD
|
|
//! \param indwWidth width of the buffer pBuffer pointes to
|
|
//! \param indwHeight height of the buffer pBuffer pointes to
|
|
//! \param x array of the x coordiantes of the three vertices
|
|
//! \param y array of the x coordiantes of the three vertices
|
|
//! \param inpSink pointer to the sink interface (is called per triangle and per triangle line)
|
|
void CallbackFillConservative(float x[3], float y[3], IRasterizeSink * inpSink);
|
|
|
|
//! subpixel correct triangle filler (conservative or not conservative)
|
|
//! \param pBuffer pointe to the DWORD
|
|
//! \param indwWidth width of the buffer pBuffer pointes to
|
|
//! \param indwHeight height of the buffer pBuffer pointes to
|
|
//! \param x array of the x coordiantes of the three vertices
|
|
//! \param y array of the x coordiantes of the three vertices
|
|
//! \param inpSink pointer to the sink interface (is called per triangle and per triangle line)
|
|
void CallbackFillSubpixelCorrect(float x[3], float y[3], IRasterizeSink * inpSink);
|
|
|
|
//!
|
|
//! /param inoutfX
|
|
//! /param inoutfY
|
|
//! /param infAmount could be positive or negative
|
|
static void ShrinkTriangle(float inoutfX[3], float inoutfY[3], float infAmount);
|
|
|
|
private:
|
|
|
|
// Clipping Rect;
|
|
|
|
int m_iMinX; //!< minimum x value included
|
|
int m_iMinY; //!< minimum y value included
|
|
int m_iMaxX; //!< maximum x value included
|
|
int m_iMaxY; //!< maximum x value included
|
|
|
|
void lambertHorizlineConservative(float fx1, float fx2, int y, IRasterizeSink* inpSink);
|
|
void lambertHorizlineSubpixelCorrect(float fx1, float fx2, int y, IRasterizeSink* inpSink);
|
|
void CopyAndSortY(const float infX[3], const float infY[3], float outfX[3], float outfY[3]);
|
|
};
|
|
|
|
|
|
// extension ideas:
|
|
// * callback with coverage mask (possible non ordered sampling)
|
|
// * z-buffer behaviour
|
|
// * gouraud shading
|
|
// * texture mapping with nearest/bicubic/bilinear filter
|
|
// * further primitives: thick line, ellipse
|
|
// * build a template version
|
|
// *
|
|
|
|
#endif // CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H
|