/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #ifndef OD_SR_FRAME_CONTEXT #define OD_SR_FRAME_CONTEXT #include "Gs/GsBaseInclude.h" #include #include "SrRenderState.h" class GsSrLineRasterizer; class GsSrTriangleRasterizer; class GsSrCircleRasterizer; class GsSrEllipseRasterizer; #include #include #include class OdGsSrVectorizeView; class OdGeEllipArc3d; class CircleDrawerNonFilled; struct PictureShift { OdInt32 x; OdInt32 y; }; class OdSrFrameContext { public: friend class OdSrUpdatePanStrategy; friend class OdSrUpdatePanDebugGreenRectsStrategy; OdSrFrameContext(); ~OdSrFrameContext(); void beginFrame(OdUInt8Array* scanLinesBuffer, OdUInt32 width, OdUInt32 height, OdUInt32 scanLineLength, bool isPerspective); void initBuffer(OdUInt8Array* scanLinesBuffer); void setClipRegion(const OdGsDCRect& clipRect); const OdGsDCRect& clipRegion() const; void setStencilBufferArea(OdUInt32 nrcWidth, OdUInt32 nrcHeight); void setStencilBufferOffset(long offsetX, long offsetY); void resetStencilBuffer(); const OdUInt8* scanLines() const { return m_state.m_pScanLines; } OdUInt32 heightInternal() { return m_state.m_height; } OdUInt32 widthInternal() { return m_state.m_width; } void drawPolygon(OdArray points); void drawTriangle(const OdGePoint3d* points, bool clipBuffer = false); void drawTexturedTriangle(const OdGePoint3d* points); void drawMultiColorTriangle(const OdGePoint3d* points); void setMatrixWorldToDevice(const OdGeMatrix3d& matrix); void setMatrixWorldToEye(const OdGeMatrix3d& matrix); void setMatrixEyeToDevice(const OdGeMatrix3d& matrix); OdGePoint2d transformPoint2d(const OdGePoint2d& point); OdGePoint2d transformPoint3d(const OdGePoint3d& point); void transformTwoPoints3dTo4ints(const OdGePoint3d* points, int& x0, int& y0, int& x1, int& y1); OdGeVector2d transformVector2d(const OdGeVector2d& point); void drawPoint(const OdGePoint3d& point, OdDb::LineWeight lineweight); void drawPolyline(OdUInt32 nPoints, const OdGePoint3d* pPoints, OdDb::LineWeight lineweight, bool closed); void drawCircle(const OdGePoint3d& center, double radius, bool filled); void drawCircularArc(const OdGePoint3d& center, double radius, const OdGeVector3d& normal, const OdGeVector3d& startVector, bool filled, double sweepAngle, OdGiArcType arcType = kOdGiArcSimple, const OdGeVector3d* pExtrusion = 0); void drawFullEllipse(const OdGePoint2d& center, double radiusMajor, double radiusMinor, OdGiArcType arcType); void drawEllipticArc( const OdGePoint2d& center, double radiusMajor, double radiusMinor, const OdGeVector2d& axisMajor, const OdGeVector2d& axisMinor, const OdGePoint2d& start, const OdGePoint2d& end, bool filled, OdGiArcType arcType, double startAngle, double endAngle); void drawColor(ODCOLORREF rgb); void setColorBuffer(const ODCOLORREF* pColors, OdUInt32 colorsLength); void applyFadingToColorBuffer(const ODCOLORREF* pOriginalColors, OdUInt32 colorsLength, ODCOLORREF fadeColor, OdUInt8 fadeValue); void draw_line(int x1, int y1, int x2, int y2, ODCOLORREF col); void draw_general_line(int x1, int y1, int x2, int y2, int lw, ODCOLORREF color); private: void drawLineSegment(const OdGePoint3d& worldP1, const OdGePoint3d& worldP2, int lineweightPixels); void drawLineSegmentEye(const OdGePoint3d& p1, const OdGePoint3d& p2, int lineweightPixels); void drawPolylineDirect(OdUInt32 nPoints, const OdGePoint3d* pPoints, int lineweightPixels, bool closed); void draw_lwLine(int x1, int y1, int x2, int y2, int lw, ODCOLORREF color); void draw_triangle(int x1, int y1, int x2, int y2, int x3, int y3, ODCOLORREF color); void draw_multicolor_triangle(float x1, float y1, float x2, float y2, float x3, float y3, const ODCOLORREF* threeColors); public: TriangleRendering::OdSrTriangleRenderer& getRenderer(); // Rasterizer friend declarations friend class GsSrLineRasterizer; friend class GsSrTriangleRasterizer; friend class GsSrCircleRasterizer; friend class GsSrEllipseRasterizer; private: void drawCircleAlgorithm(int centerX, int centerY, int radius); void drawEllipseAlgorithm(int centerX, int centerY, int radiusMajor, int radiusMinor); void drawFilledEllipseAlgorithm(int centerX, int centerY, int radiusMajor, int radiusMinor); void draw_filled_circle(int x, int y, double radius, ODCOLORREF color); void draw_filled_circle_precise(double x, double y, double radius, ODCOLORREF color); public: GsSrRenderState m_state; OdGsSrVectorizeView* view() { return m_pCurrentView; } void setCurrentView(OdGsSrVectorizeView* view) { m_pCurrentView = view; } private: OdGsSrVectorizeView* m_pCurrentView; inline OdUInt8* getPixPtr(int x, int y) { return m_state.m_pScanLines + m_state.m_scanLineLength * y + x * 3; } public: void setTextureData( const OdUInt8* data, OdUInt32 width, OdUInt32 height, OdUInt32 scanLineLength, const OdGiRasterImage::PixelFormatInfo& pixelFormat, const OdSrTextureTransform& transform, const OdSrTextureParams& params); void resetTexture(); public: inline void draw_point(int x, int y, ODCOLORREF color) { y = m_state.m_height - 1 - y; if (x >= m_state.m_clipRegion.m_min.x && x <= m_state.m_clipRegion.m_max.x && y >= m_state.m_clipRegion.m_min.y && y <= m_state.m_clipRegion.m_max.y) { OdUInt32 idx = (y - m_state.m_stencilOffsetY) * m_state.m_stencilWidth + (x - m_state.m_stencilOffsetX); if (!m_state.m_pStencilScanlinesPtr || (idx < m_state.m_pStencilScanlines.size() && m_state.m_pStencilScanlinesPtr[idx])) { putPixel(x, y, color); } } } inline void draw_horizontalLine(int y, int x1, int x2, ODCOLORREF color) { if (y <= (int)m_state.m_clipRegion.m_max.y && y >= m_state.m_clipRegion.m_min.y) { int i; if (x1 > x2) { i = x1; x1 = x2; x2 = i; } if (x1 < m_state.m_clipRegion.m_min.x) x1 = m_state.m_clipRegion.m_min.x; if (x2 > (int)m_state.m_clipRegion.m_max.x) x2 = m_state.m_clipRegion.m_max.x; if (x1 <= x2) { OdUInt8 blue = ODGETBLUE(color); OdUInt8 green = ODGETGREEN(color); OdUInt8 red = ODGETRED(color); OdUInt8 alpha = ODGETALPHA(color); OdUInt8* pPtr = m_state.m_pScanLines + m_state.m_scanLineLength * y + x1 * 3; if (!m_state.m_pStencilScanlinesPtr) { if (alpha == 255) { for (i = 0; i < x2 - x1 + 1; i++) { *(pPtr++) = blue; *(pPtr++) = green; *(pPtr++) = red; } } else if (alpha != 0) { for (i = 0; i < x2 - x1 + 1; i++) { OdMergeRGBAlpha(pPtr[2], pPtr[1], pPtr[0], red, green, blue, alpha, pPtr[2], pPtr[1], pPtr[0]); pPtr += 3; } } } else { OdUInt8* pStencil = m_state.m_pStencilScanlinesPtr + (y - m_state.m_stencilOffsetY) * m_state.m_stencilWidth + (x1 - m_state.m_stencilOffsetX); if (alpha == 255) { for (i = 0; i < x2 - x1 + 1; i++) { if (*pStencil) { *(pPtr++) = blue; *(pPtr++) = green; *(pPtr++) = red; } else { pPtr += 3; } pStencil++; } } else if (alpha != 0) { for (i = 0; i < x2 - x1 + 1; i++) { if (*pStencil) { OdMergeRGBAlpha(pPtr[2], pPtr[1], pPtr[0], red, green, blue, alpha, pPtr[2], pPtr[1], pPtr[0]); } pPtr += 3; pStencil++; } } } } } } private: void draw_clipping_triangle(int x1, int y1, int x2, int y2, int x3, int y3); inline void draw_horizontalLineStencil(int y, int x1, int x2, GsSrRenderState::ClippingAreaType clippingType) { //if (y <= (int)m_state.m_clipRegion.m_max.y && y >= m_state.m_clipRegion.m_min.y) { int i; if (x1 > x2) { i = x1; x1 = x2; x2 = i; } if (x1 < m_state.m_clipRegion.m_min.x) x1 = m_state.m_clipRegion.m_min.x; if (x2 > (int)m_state.m_clipRegion.m_max.x) x2 = m_state.m_clipRegion.m_max.x; OdUInt32 idx = m_state.m_stencilWidth * (y - m_state.m_stencilOffsetY) + (x1 - m_state.m_stencilOffsetX); if (x1 <= x2 && idx < m_state.m_pStencilScanlines.size()) { OdUInt8* pPtr = m_state.m_pStencilScanlinesPtr + idx; for (i = 0; i < (x2 - x1 + 1) && idx < m_state.m_pStencilScanlines.size(); i++, idx++, pPtr++) { SETBIT_1(*pPtr, clippingType); } } } } void putPixel(int x, int y, ODCOLORREF color); }; #endif // OD_SR_FRAME_CONTEXT