diff --git a/ScanlineRendering/.vscode/launch.json b/ScanlineRendering/.vscode/launch.json new file mode 100644 index 0000000..850ce87 --- /dev/null +++ b/ScanlineRendering/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Visual Studio: Start Debugging", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}\\x64\\Debug\\${workspaceFolderBasename}.exe", + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "preLaunchTask": "Visual Studio: Build Solution", + "internalConsoleOptions": "neverOpen" + } + ], + "version": "0.2.0" +} \ No newline at end of file diff --git a/ScanlineRendering/.vscode/settings.json b/ScanlineRendering/.vscode/settings.json new file mode 100644 index 0000000..d47ab15 --- /dev/null +++ b/ScanlineRendering/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "git.openRepositoryInParentFolders": "never" +} \ No newline at end of file diff --git a/ScanlineRendering/.vscode/tasks.json b/ScanlineRendering/.vscode/tasks.json new file mode 100644 index 0000000..6e0a647 --- /dev/null +++ b/ScanlineRendering/.vscode/tasks.json @@ -0,0 +1,23 @@ +{ + "tasks": [ + { + "type": "shell", + "label": "Visual Studio: Build Solution", + "command": "msbuild", + "args": [ + "${workspaceFolder}\\${workspaceFolderBasename}.sln", + "/p:Configuration=Debug", + "/p:Platform=x64" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": [ + "$msCompile" + ], + "group": "build", + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/ScanlineRendering/ScanlineRendering.sln b/ScanlineRendering/ScanlineRendering.sln new file mode 100644 index 0000000..ea5583c --- /dev/null +++ b/ScanlineRendering/ScanlineRendering.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35312.102 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScanlineRendering", "ScanlineRendering\ScanlineRendering.vcxproj", "{3EC85626-3F98-4D34-9385-A18DEBE0A564}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3EC85626-3F98-4D34-9385-A18DEBE0A564}.Debug|x64.ActiveCfg = Debug|x64 + {3EC85626-3F98-4D34-9385-A18DEBE0A564}.Debug|x64.Build.0 = Debug|x64 + {3EC85626-3F98-4D34-9385-A18DEBE0A564}.Debug|x86.ActiveCfg = Debug|Win32 + {3EC85626-3F98-4D34-9385-A18DEBE0A564}.Debug|x86.Build.0 = Debug|Win32 + {3EC85626-3F98-4D34-9385-A18DEBE0A564}.Release|x64.ActiveCfg = Release|x64 + {3EC85626-3F98-4D34-9385-A18DEBE0A564}.Release|x64.Build.0 = Release|x64 + {3EC85626-3F98-4D34-9385-A18DEBE0A564}.Release|x86.ActiveCfg = Release|Win32 + {3EC85626-3F98-4D34-9385-A18DEBE0A564}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7EE7C82A-6EB5-426B-BB34-CB82952670F8} + EndGlobalSection +EndGlobal diff --git a/ScanlineRendering/ScanlineRendering/AET.cpp b/ScanlineRendering/ScanlineRendering/AET.cpp new file mode 100644 index 0000000..b92ab9a --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/AET.cpp @@ -0,0 +1,8 @@ +#include "pch.h" +#include "AET.h" + +CAET::CAET() { +} + +CAET::~CAET() { +} \ No newline at end of file diff --git a/ScanlineRendering/ScanlineRendering/AET.h b/ScanlineRendering/ScanlineRendering/AET.h new file mode 100644 index 0000000..6290a60 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/AET.h @@ -0,0 +1,16 @@ +#pragma once +#include "Pi2.h" + +class CAET { +public: + CAET(); + virtual ~CAET(); + +public: + double x; + int yMax; + double k; + CPi2 ps; + CPi2 pe; + CAET *pNext; +}; diff --git a/ScanlineRendering/ScanlineRendering/Bucket.cpp b/ScanlineRendering/ScanlineRendering/Bucket.cpp new file mode 100644 index 0000000..4d5ed8d --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/Bucket.cpp @@ -0,0 +1,8 @@ +#include "pch.h" +#include "Bucket.h" + +CBucket::CBucket() { +} + +CBucket::~CBucket() { +} diff --git a/ScanlineRendering/ScanlineRendering/Bucket.h b/ScanlineRendering/ScanlineRendering/Bucket.h new file mode 100644 index 0000000..10d3c64 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/Bucket.h @@ -0,0 +1,13 @@ +#pragma once +#include "AET.h" + +class CBucket { +public: + CBucket(); + virtual ~CBucket(); + +public: + int ScanLine; + CAET *pET; + CBucket *pNext; +}; diff --git a/ScanlineRendering/ScanlineRendering/Fill.cpp b/ScanlineRendering/ScanlineRendering/Fill.cpp new file mode 100644 index 0000000..1a5a271 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/Fill.cpp @@ -0,0 +1,245 @@ +#include "pch.h" +#include +#include "Fill.h" +#define Round(x) (int)(x + 0.5) + +CFill::CFill() { + PNum = 0; + P = NULL; + pEdge = NULL; + pHeadB = NULL; + pHeadE = NULL; +} + +CFill::~CFill() { + if (P != NULL) { + delete[] P; + P = NULL; + } + ClearMemory(); +} + +void CFill::SetPoint(CPi2 *p, int m) { + P = new CPi2[m]; + for (int i = 0; i < m; i++) { + P[i] = p[i]; + } + PNum = m; +} + +void CFill::CreateBucket() { + int yMin, yMax; + yMin = yMax = P[0].y; + for (int i = 0; i < PNum; i++) { + if (P[i].y < yMin) { + yMin = P[i].y; + } + if (P[i].y > yMax) { + yMax = P[i].y; + } + } + for (int y = yMin; y <= yMax; y++) { + if (yMin == y) { + pHeadB = new CBucket; + pCurrentB = pHeadB; + pCurrentB->ScanLine = yMin; + pCurrentB->pET = NULL; + pCurrentB->pNext = NULL; + } + else { + pCurrentB->pNext = new CBucket; + pCurrentB = pCurrentB->pNext; + pCurrentB->ScanLine = y; + pCurrentB->pET = NULL; + pCurrentB->pNext = NULL; + } + } +} + +void CFill::CreateEdge() { + for (int i = 0; i < PNum; i++) { + pCurrentB = pHeadB; + int j = (i + 1) % PNum; + if (P[i].y < P[j].y) { + pEdge = new CAET; + pEdge->x = P[i].x; + pEdge->yMax = P[j].y; + pEdge->k = (P[j].x - P[i].x) / (P[j].y - P[i].y); + pEdge->ps = P[i]; + pEdge->pe = P[j]; + pEdge->pNext = NULL; + while (pCurrentB->ScanLine != P[i].y) { + pCurrentB = pCurrentB->pNext; + } + } + if (P[j].y < P[i].y) { + pEdge = new CAET; + pEdge->x = P[j].x; + pEdge->yMax = P[i].y; + pEdge->k = (P[i].x - P[j].x) / (P[i].y - P[j].y); + pEdge->ps = P[i]; + pEdge->pe = P[j]; + pEdge->pNext = NULL; + while (pCurrentB->ScanLine != P[j].y) { + pCurrentB = pCurrentB->pNext; + } + } + if (P[i].y != P[j].y) { + pCurrentE = pCurrentB->pET; + if (pCurrentE == NULL) { + pCurrentE = pEdge; + pCurrentB->pET = pCurrentE; + } + else { + while (pCurrentE->pNext != NULL) { + pCurrentE = pCurrentE->pNext; + } + pCurrentE->pNext = pEdge; + } + } + } +} + +void CFill::Gouraud(CDC *pDC) { + CAET *pT1 = NULL, *pT2 = NULL; + pHeadE = NULL; + for (pCurrentB = pHeadB; pCurrentB != NULL; pCurrentB = pCurrentB->pNext) { + for (pCurrentE = pCurrentB->pET; pCurrentE != NULL; pCurrentE = pCurrentE->pNext) { + pEdge = new CAET; + pEdge->x = pCurrentE->x; + pEdge->yMax = pCurrentE->yMax; + pEdge->k = pCurrentE->k; + pEdge->ps = pCurrentE->ps; + pEdge->pe = pCurrentE->pe; + pEdge->pNext = NULL; + AddET(pEdge); + } + ETOrder(); + pT1 = pHeadE; + if (pT1 == NULL) + return; + while (pCurrentB->ScanLine >= pT1->yMax) { + CAET *pAETTEmp = pT1; + pT1 = pT1->pNext; + delete pAETTEmp; + pHeadE = pT1; + if (pHeadE == NULL) + return; + } + if (pT1->pNext != NULL) { + pT2 = pT1; + pT1 = pT2->pNext; + } + while (pT1 != NULL) { + if (pCurrentB->ScanLine >= pT1->yMax) { + CAET *pAETTemp = pT1; + pT2->pNext = pT1->pNext; + pT1 = pT2->pNext; + delete pAETTemp; + } + else { + pT2 = pT1; + pT1 = pT2->pNext; + } + } + BOOL bInFlag = FALSE; + double xb, xe; + CRGB cb, ce, c; + for (pT1 = pHeadE; pT1 != NULL; pT1 = pT1->pNext) { + if (FALSE == bInFlag) { + xb = pT1->x; + cb = LinearDifferential(pT1->ps.y, pCurrentB->ScanLine, pT1->pe.y, pT1->ps.c, pT1->pe.c); + bInFlag = TRUE; + } + else { + xe = pT1->x; + ce = LinearDifferential(pT1->ps.y, pCurrentB->ScanLine, pT1->pe.y, pT1->ps.c, pT1->pe.c); + for (double x = xb; x < xe; x++) { + c = LinearDifferential(xb, x, xe, cb, ce); + pDC->SetPixelV(Round(x), pCurrentB->ScanLine, RGB(c.red * 255, c.green * 255, c.blue * 255)); + } + bInFlag = FALSE; + } + } + for (pT1 = pHeadE; pT1 != NULL; pT1 = pT1->pNext) { + pT1->x = pT1->x + pT1->k; + } + } +} + +void CFill::AddET(CAET *pNewEdge) { + CAET *pCE = pHeadE; + if (pCE == NULL) { + pHeadE = pNewEdge; + pCE = pHeadE; + } + else { + while (pCE->pNext != NULL) { + pCE = pCE->pNext; + } + pCE->pNext = pNewEdge; + } +} + +void CFill::ETOrder() { + CAET *pT1, *pT2; + int Count = 1; + pT1 = pHeadE; + if (pT1 == NULL) { + return; + } + if (pT1->pNext == NULL) { + return; + } + while (pT1->pNext != NULL) { + Count++; + pT1 = pT1->pNext; + } + for (int i = 0; i < Count - 1; i++) { + CAET **pPre = &pHeadE; + pT1 = pHeadE; + for (int j = 0; j < Count - 1 - i; j++) { + pT2 = pT1->pNext; + + if ((pT1->x > pT2->x) || ((pT1->x == pT2->x) && (pT1->k > pT2->k))) { + pT1->pNext = pT2->pNext; + pT2->pNext = pT1; + *pPre = pT2; + pPre = &(pT2->pNext); + } + else { + pPre = &(pT1->pNext); + pT1 = pT1->pNext; + } + } + } +} + +void CFill::ClearMemory() { + DeleteAETChain(pHeadE); + CBucket *pBucket = pHeadB; + while (pBucket != NULL) { + CBucket *pBucketTemp = pBucket->pNext; + DeleteAETChain(pBucket->pET); + delete pBucket; + pBucket = pBucketTemp; + } + pHeadB = NULL; + pHeadE = NULL; +} + +void CFill::DeleteAETChain(CAET *pAET) { + while (pAET != NULL) { + CAET *pAETTemp = pAET->pNext; + delete pAET; + pAET = pAETTemp; + } +} + +CRGB CFill::LinearDifferential(double y0, double y, double y1, CRGB c0, CRGB c1) { + CRGB c; + double t; + t = (y - y0) / (y1 - y0); + c = (1 - t) * c0 + t * c1; + return c; +} diff --git a/ScanlineRendering/ScanlineRendering/Fill.h b/ScanlineRendering/ScanlineRendering/Fill.h new file mode 100644 index 0000000..c40852f --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/Fill.h @@ -0,0 +1,25 @@ +#pragma once +#include "Bucket.h" + +class CFill { +public: + CFill(); + virtual ~CFill(); + void SetPoint(CPi2 *p, int); + void CreateBucket(); + void CreateEdge(); + void AddET(CAET *); + void ETOrder(); + void Gouraud(CDC *); + void ClearMemory(); + void DeleteAETChain(CAET *pAET); + +protected: + int PNum; + CPi2 *P; + CAET *pHeadE, *pCurrentE, *pEdge; + CBucket *pHeadB, *pCurrentB; + +public: + CRGB LinearDifferential(double y0, double y, double y1, CRGB c0, CRGB c1); +}; diff --git a/ScanlineRendering/ScanlineRendering/Line.cpp b/ScanlineRendering/ScanlineRendering/Line.cpp new file mode 100644 index 0000000..d0be8cc --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/Line.cpp @@ -0,0 +1,110 @@ +#include "pch.h" +#include +#include "Line.h" +#define Round(x) (int)(x + 0.5) + +CLine::CLine() { +} + +CLine::~CLine() { +} + +void CLine::MoveTo(CDC *pDC, CP2 p0) { + P0 = p0; +} + +void CLine::MoveTo(CDC *pDC, double x0, double y0) { + P0 = CP2(x0, y0); +} + +void CLine::LineTo(CDC *pDC, CP2 p1) { + P1 = p1; + CP2 p, t; + if (fabs(P0.x - P1.x) < 1e-6) { + if (P0.y > P1.y) { + t = P0; + P0 = P1; + P1 = t; + } + for (p = P0; p.y < P1.y; p.y++) { + pDC->SetPixelV(Round(p.x), Round(p.y), RGB(0, 0, 0)); + } + } + else { + double k, d; + k = (P1.y - P0.y) / (P1.x - P0.x); + if (k > 1.0) { + if (P0.y > P1.y) { + t = P0; + P0 = P1; + P1 = t; + } + d = 1 - 0.5 * k; + for (p = P0; p.y < P1.y; p.y++) { + pDC->SetPixelV(Round(p.x), Round(p.y), RGB(0, 0, 0)); + if (d >= 0) { + p.x++; + d += 1 - k; + } + else + d += 1; + } + } + if (0.0 <= k && k <= 1.0) { + if (P0.x > P1.x) { + t = P0; + P0 = P1; + P1 = t; + } + d = 0.5 - k; + for (p = P0; p.x < P1.x; p.x++) { + pDC->SetPixelV(Round(p.x), Round(p.y), RGB(0, 0, 0)); + if (d < 0) { + p.y++; + d += 1 - k; + } + else + d -= k; + } + } + if (k >= -1.0 && k < 0.0) { + if (P0.x > P1.x) { + t = P0; + P0 = P1; + P1 = t; + } + d = -0.5 - k; + for (p = P0; p.x < P1.x; p.x++) { + pDC->SetPixelV(Round(p.x), Round(p.y), RGB(0, 0, 0)); + if (d > 0) { + p.y--; + d -= 1 + k; + } + else + d -= k; + } + } + if (k < -1.0) { + if (P0.y < P1.y) { + t = P0; + P0 = P1; + P1 = t; + } + d = -1 - 0.5 * k; + for (p = P0; p.y > P1.y; p.y--) { + pDC->SetPixelV(Round(p.x), Round(p.y), RGB(0, 0, 0)); + if (d < 0) { + p.x++; + d -= 1 + k; + } + else + d -= 1; + } + } + } + P0 = p1; +} + +void CLine::LineTo(CDC *pDC, double x1, double y1) { + LineTo(pDC, CP2(x1, y1)); +} diff --git a/ScanlineRendering/ScanlineRendering/Line.h b/ScanlineRendering/ScanlineRendering/Line.h new file mode 100644 index 0000000..067896c --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/Line.h @@ -0,0 +1,17 @@ +#pragma once +#include "P2.h" +#include "RGB.h" + +class CLine { +public: + CLine(); + virtual ~CLine(); + void MoveTo(CDC *, CP2); + void MoveTo(CDC *, double, double); + void LineTo(CDC *, CP2); + void LineTo(CDC *, double, double); + +public: + CP2 P0; + CP2 P1; +}; diff --git a/ScanlineRendering/ScanlineRendering/MainFrm.cpp b/ScanlineRendering/ScanlineRendering/MainFrm.cpp new file mode 100644 index 0000000..55eb43b --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/MainFrm.cpp @@ -0,0 +1,84 @@ + +// MainFrm.cpp : implementation of the CMainFrame class +// + +#include "pch.h" +#include "framework.h" +#include "ScanlineRendering.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) +ON_WM_CREATE() +END_MESSAGE_MAP() + +static UINT indicators[] = { + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() noexcept { + // TODO: add member initialization code here +} + +CMainFrame::~CMainFrame() { +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || + !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { + TRACE0("Failed to create toolbar\n"); + return -1; // fail to create + } + + if (!m_wndStatusBar.Create(this)) { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + m_wndStatusBar.SetIndicators(indicators, sizeof(indicators) / sizeof(UINT)); + + // TODO: Delete these three lines if you don't want the toolbar to be dockable + m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); + EnableDocking(CBRS_ALIGN_ANY); + DockControlBar(&m_wndToolBar); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT &cs) { + if (!CFrameWnd::PreCreateWindow(cs)) + return FALSE; + // TODO: Modify the Window class or styles here by modifying + // the CREATESTRUCT cs + + return TRUE; +} + +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const { + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext &dc) const { + CFrameWnd::Dump(dc); +} +#endif //_DEBUG + +// CMainFrame message handlers diff --git a/ScanlineRendering/ScanlineRendering/MainFrm.h b/ScanlineRendering/ScanlineRendering/MainFrm.h new file mode 100644 index 0000000..a0ca85e --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/MainFrm.h @@ -0,0 +1,37 @@ + +// MainFrm.h : interface of the CMainFrame class +// + +#pragma once + +class CMainFrame : public CFrameWnd { + +protected: // create from serialization only + CMainFrame() noexcept; + DECLARE_DYNCREATE(CMainFrame) + + // Attributes +public: + // Operations +public: + // Overrides +public: + virtual BOOL PreCreateWindow(CREATESTRUCT &cs); + + // Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext &dc) const; +#endif + +protected: // control bar embedded members + CToolBar m_wndToolBar; + CStatusBar m_wndStatusBar; + + // Generated message map functions +protected: + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + DECLARE_MESSAGE_MAP() +}; diff --git a/ScanlineRendering/ScanlineRendering/P2.cpp b/ScanlineRendering/ScanlineRendering/P2.cpp new file mode 100644 index 0000000..1bcd616 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/P2.cpp @@ -0,0 +1,16 @@ +#include "pch.h" +#include "P2.h" + +CP2::CP2() { + x = 0.0; + y = 0.0; + c = CRGB(1.0, 1.0, 1.0); +} + +CP2::~CP2() { +} + +CP2::CP2(double x, double y) { + this->x = x; + this->y = y; +} diff --git a/ScanlineRendering/ScanlineRendering/P2.h b/ScanlineRendering/ScanlineRendering/P2.h new file mode 100644 index 0000000..a7985e7 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/P2.h @@ -0,0 +1,14 @@ +#pragma once +#include "RGB.h" + +class CP2 { +public: + CP2(); + virtual ~CP2(); + CP2(double, double); + +public: + double x; + double y; + CRGB c; +}; diff --git a/ScanlineRendering/ScanlineRendering/Pi2.cpp b/ScanlineRendering/ScanlineRendering/Pi2.cpp new file mode 100644 index 0000000..afd468d --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/Pi2.cpp @@ -0,0 +1,16 @@ +#include "pch.h" +#include "Pi2.h" + +CPi2::CPi2() { + this->x = 0.0; + this->y = 0; + this->c = CRGB(0.0, 1.0, 1.0); +} + +CPi2::~CPi2() { +} + +CPi2::CPi2(double x, int y) { + this->x = x; + this->y = y; +} diff --git a/ScanlineRendering/ScanlineRendering/Pi2.h b/ScanlineRendering/ScanlineRendering/Pi2.h new file mode 100644 index 0000000..fe8452d --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/Pi2.h @@ -0,0 +1,12 @@ +#pragma once +#include "RGB.h" + +class CPi2 { +public: + CPi2(); + virtual ~CPi2(); + CPi2(double, int); + double x; + int y; + CRGB c; +}; diff --git a/ScanlineRendering/ScanlineRendering/RGB.cpp b/ScanlineRendering/ScanlineRendering/RGB.cpp new file mode 100644 index 0000000..78c0d13 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/RGB.cpp @@ -0,0 +1,98 @@ +#include "pch.h" +#include "RGB.h" + +CRGB::CRGB() { + red = 1.0; + green = 1.0; + blue = 1.0; +} +CRGB::CRGB(double r, double g, double b) { + red = r; + green = g; + blue = b; +} + +CRGB::~CRGB() { +} + +CRGB operator+(const CRGB &c1, const CRGB &c2) { + CRGB c; + c.red = c1.red + c2.red; + c.green = c1.green + c2.green; + c.blue = c1.blue + c2.blue; + return c; +} + +CRGB operator-(const CRGB &c1, const CRGB &c2) { + CRGB c; + c.red = c1.red - c2.red; + c.green = c1.green - c2.green; + c.blue = c1.blue - c2.blue; + return c; +} + +CRGB operator*(const CRGB &c1, const CRGB &c2) { + CRGB c; + c.red = c1.red * c2.red; + c.green = c1.green * c2.green; + c.blue = c1.blue * c2.blue; + return c; +} + +CRGB operator*(const CRGB &c1, double k) { + CRGB c; + c.red = k * c1.red; + c.green = k * c1.green; + c.blue = k * c1.blue; + return c; +} + +CRGB operator*(double k, const CRGB &c1) { + CRGB c; + c.red = k * c1.red; + c.green = k * c1.green; + c.blue = k * c1.blue; + return c; +} + +CRGB operator/(const CRGB &c1, double k) { + CRGB c; + c.red = c1.red / k; + c.green = c1.green / k; + c.blue = c1.blue / k; + return c; +} + +CRGB operator+=(CRGB &c1, CRGB &c2) { + c1.red = c1.red + c2.red; + c1.green = c1.green + c2.green; + c1.blue = c1.blue + c2.blue; + return c1; +} + +CRGB operator-=(CRGB &c1, CRGB &c2) { + c1.red = c1.red - c2.red; + c1.green = c1.green - c2.green; + c1.blue = c1.blue - c2.blue; + return c1; +} + +CRGB operator*=(CRGB &c1, CRGB &c2) { + c1.red = c1.red * c2.red; + c1.green = c1.green * c2.green; + c1.blue = c1.blue * c2.blue; + return c1; +} + +CRGB operator/=(CRGB &c1, double k) { + c1.red = c1.red / k; + c1.green = c1.green / k; + c1.blue = c1.blue / k; + return c1; +} + +void CRGB::Normalize() { + red = (red < 0.0) ? 0.0 : ((red > 1.0) ? 1.0 : red); + green = (green < 0.0) ? 0.0 : ((green > 1.0) ? 1.0 : green); + blue = (blue < 0.0) ? 0.0 : ((blue > 1.0) ? 1.0 : blue); +} diff --git a/ScanlineRendering/ScanlineRendering/RGB.h b/ScanlineRendering/ScanlineRendering/RGB.h new file mode 100644 index 0000000..0a73a3c --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/RGB.h @@ -0,0 +1,24 @@ +#pragma once + +class CRGB { +public: + CRGB(); + CRGB(double, double, double); + virtual ~CRGB(); + friend CRGB operator+(const CRGB &, const CRGB &); + friend CRGB operator-(const CRGB &, const CRGB &); + friend CRGB operator*(const CRGB &, const CRGB &); + friend CRGB operator*(const CRGB &, double); + friend CRGB operator*(double, const CRGB &); + friend CRGB operator/(const CRGB &, double); + friend CRGB operator+=(CRGB &, CRGB &); + friend CRGB operator-=(CRGB &, CRGB &); + friend CRGB operator*=(CRGB &, CRGB &); + friend CRGB operator/=(CRGB &, double); + void Normalize(); + +public: + double red; + double green; + double blue; +}; diff --git a/ScanlineRendering/ScanlineRendering/Resource.h b/ScanlineRendering/ScanlineRendering/Resource.h new file mode 100644 index 0000000..ef15e4d --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/Resource.h @@ -0,0 +1,19 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ScanlineRendering.rc +// +#define IDD_ABOUTBOX 100 +#define IDP_OLE_INIT_FAILED 100 +#define IDR_MAINFRAME 128 +#define IDR_ScanlineRenderingTYPE 130 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 310 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 310 +#define _APS_NEXT_COMMAND_VALUE 32771 +#endif +#endif diff --git a/ScanlineRendering/ScanlineRendering/ScanlineRendering.cpp b/ScanlineRendering/ScanlineRendering/ScanlineRendering.cpp new file mode 100644 index 0000000..051eea4 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/ScanlineRendering.cpp @@ -0,0 +1,164 @@ + +// ScanlineRendering.cpp : Defines the class behaviors for the application. +// + +#include "pch.h" +#include "framework.h" +#include "afxwinappex.h" +#include "afxdialogex.h" +#include "ScanlineRendering.h" +#include "MainFrm.h" + +#include "ScanlineRenderingDoc.h" +#include "ScanlineRenderingView.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +// CScanlineRenderingApp + +BEGIN_MESSAGE_MAP(CScanlineRenderingApp, CWinApp) +ON_COMMAND(ID_APP_ABOUT, &CScanlineRenderingApp::OnAppAbout) +// Standard file based document commands +ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew) +ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen) +// Standard print setup command +ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup) +END_MESSAGE_MAP() + +// CScanlineRenderingApp construction + +CScanlineRenderingApp::CScanlineRenderingApp() noexcept { + + // support Restart Manager + m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS; +#ifdef _MANAGED + // If the application is built using Common Language Runtime support (/clr): + // 1) This additional setting is needed for Restart Manager support to work properly. + // 2) In your project, you must add a reference to System.Windows.Forms in order to build. + System::Windows::Forms::Application::SetUnhandledExceptionMode(System::Windows::Forms::UnhandledExceptionMode::ThrowException); +#endif + + // TODO: replace application ID string below with unique ID string; recommended + // format for string is CompanyName.ProductName.SubProduct.VersionInformation + SetAppID(_T("ScanlineRendering.AppID.NoVersion")); + + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +// The one and only CScanlineRenderingApp object + +CScanlineRenderingApp theApp; + +// CScanlineRenderingApp initialization + +BOOL CScanlineRenderingApp::InitInstance() { + // InitCommonControlsEx() is required on Windows XP if an application + // manifest specifies use of ComCtl32.dll version 6 or later to enable + // visual styles. Otherwise, any window creation will fail. + INITCOMMONCONTROLSEX InitCtrls; + InitCtrls.dwSize = sizeof(InitCtrls); + // Set this to include all the common control classes you want to use + // in your application. + InitCtrls.dwICC = ICC_WIN95_CLASSES; + InitCommonControlsEx(&InitCtrls); + + CWinApp::InitInstance(); + + // Initialize OLE libraries + if (!AfxOleInit()) { + AfxMessageBox(IDP_OLE_INIT_FAILED); + return FALSE; + } + + AfxEnableControlContainer(); + + EnableTaskbarInteraction(FALSE); + + // AfxInitRichEdit2() is required to use RichEdit control + // AfxInitRichEdit2(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need + // Change the registry key under which our settings are stored + // TODO: You should modify this string to be something appropriate + // such as the name of your company or organization + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + LoadStdProfileSettings(4); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views + CSingleDocTemplate *pDocTemplate; + pDocTemplate = new CSingleDocTemplate( + IDR_MAINFRAME, + RUNTIME_CLASS(CScanlineRenderingDoc), + RUNTIME_CLASS(CMainFrame), // main SDI frame window + RUNTIME_CLASS(CScanlineRenderingView)); + if (!pDocTemplate) + return FALSE; + AddDocTemplate(pDocTemplate); + + // Parse command line for standard shell commands, DDE, file open + CCommandLineInfo cmdInfo; + ParseCommandLine(cmdInfo); + + // Dispatch commands specified on the command line. Will return FALSE if + // app was launched with /RegServer, /Register, /Unregserver or /Unregister. + if (!ProcessShellCommand(cmdInfo)) + return FALSE; + + // The one and only window has been initialized, so show and update it + m_pMainWnd->ShowWindow(SW_SHOW); + m_pMainWnd->UpdateWindow(); + return TRUE; +} + +int CScanlineRenderingApp::ExitInstance() { + // TODO: handle additional resources you may have added + AfxOleTerm(FALSE); + + return CWinApp::ExitInstance(); +} + +// CScanlineRenderingApp message handlers + +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialogEx { +public: + CAboutDlg() noexcept; + +// Dialog Data +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_ABOUTBOX }; +#endif + +protected: + virtual void DoDataExchange(CDataExchange *pDX); // DDX/DDV support + + // Implementation +protected: + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() noexcept : CDialogEx(IDD_ABOUTBOX) { +} + +void CAboutDlg::DoDataExchange(CDataExchange *pDX) { + CDialogEx::DoDataExchange(pDX); +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) +END_MESSAGE_MAP() + +// App command to run the dialog +void CScanlineRenderingApp::OnAppAbout() { + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +// CScanlineRenderingApp message handlers diff --git a/ScanlineRendering/ScanlineRendering/ScanlineRendering.h b/ScanlineRendering/ScanlineRendering/ScanlineRendering.h new file mode 100644 index 0000000..d8b0ebf --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/ScanlineRendering.h @@ -0,0 +1,30 @@ + +// ScanlineRendering.h : main header file for the ScanlineRendering application +// +#pragma once + +#ifndef __AFXWIN_H__ +#error "include 'pch.h' before including this file for PCH" +#endif + +#include "resource.h" // main symbols + +// CScanlineRenderingApp: +// See ScanlineRendering.cpp for the implementation of this class +// + +class CScanlineRenderingApp : public CWinApp { +public: + CScanlineRenderingApp() noexcept; + + // Overrides +public: + virtual BOOL InitInstance(); + virtual int ExitInstance(); + + // Implementation + afx_msg void OnAppAbout(); + DECLARE_MESSAGE_MAP() +}; + +extern CScanlineRenderingApp theApp; diff --git a/ScanlineRendering/ScanlineRendering/ScanlineRendering.rc b/ScanlineRendering/ScanlineRendering/ScanlineRendering.rc new file mode 100644 index 0000000..3492ff0 Binary files /dev/null and b/ScanlineRendering/ScanlineRendering/ScanlineRendering.rc differ diff --git a/ScanlineRendering/ScanlineRendering/ScanlineRendering.vcxproj b/ScanlineRendering/ScanlineRendering/ScanlineRendering.vcxproj new file mode 100644 index 0000000..a2d9481 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/ScanlineRendering.vcxproj @@ -0,0 +1,243 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {3EC85626-3F98-4D34-9385-A18DEBE0A564} + MFCProj + ScanlineRendering + 10.0 + + + + Application + true + v143 + Unicode + Dynamic + + + Application + false + v143 + true + Unicode + Dynamic + + + Application + true + v143 + Unicode + Dynamic + + + Application + false + v143 + true + Unicode + Dynamic + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + true + _WINDOWS;_DEBUG;%(PreprocessorDefinitions) + pch.h + + + Windows + + + false + true + _DEBUG;%(PreprocessorDefinitions) + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + true + WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) + pch.h + + + Windows + + + false + true + _DEBUG;%(PreprocessorDefinitions) + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + true + true + true + WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + pch.h + + + Windows + true + true + + + false + true + NDEBUG;%(PreprocessorDefinitions) + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + true + true + true + _WINDOWS;NDEBUG;%(PreprocessorDefinitions) + pch.h + + + Windows + true + true + + + false + true + NDEBUG;%(PreprocessorDefinitions) + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ScanlineRendering/ScanlineRendering/ScanlineRendering.vcxproj.filters b/ScanlineRendering/ScanlineRendering/ScanlineRendering.vcxproj.filters new file mode 100644 index 0000000..80a9613 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/ScanlineRendering.vcxproj.filters @@ -0,0 +1,123 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Resource Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/ScanlineRendering/ScanlineRendering/ScanlineRendering.vcxproj.user b/ScanlineRendering/ScanlineRendering/ScanlineRendering.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/ScanlineRendering.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ScanlineRendering/ScanlineRendering/ScanlineRenderingDoc.cpp b/ScanlineRendering/ScanlineRendering/ScanlineRenderingDoc.cpp new file mode 100644 index 0000000..fecfbe4 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/ScanlineRenderingDoc.cpp @@ -0,0 +1,118 @@ + +// ScanlineRenderingDoc.cpp : implementation of the CScanlineRenderingDoc class +// + +#include "pch.h" +#include "framework.h" +// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail +// and search filter handlers and allows sharing of document code with that project. +#ifndef SHARED_HANDLERS +#include "ScanlineRendering.h" +#endif + +#include "ScanlineRenderingDoc.h" + +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +// CScanlineRenderingDoc + +IMPLEMENT_DYNCREATE(CScanlineRenderingDoc, CDocument) + +BEGIN_MESSAGE_MAP(CScanlineRenderingDoc, CDocument) +END_MESSAGE_MAP() + +// CScanlineRenderingDoc construction/destruction + +CScanlineRenderingDoc::CScanlineRenderingDoc() noexcept { + // TODO: add one-time construction code here +} + +CScanlineRenderingDoc::~CScanlineRenderingDoc() { +} + +BOOL CScanlineRenderingDoc::OnNewDocument() { + if (!CDocument::OnNewDocument()) + return FALSE; + + // TODO: add reinitialization code here + // (SDI documents will reuse this document) + + return TRUE; +} + +// CScanlineRenderingDoc serialization + +void CScanlineRenderingDoc::Serialize(CArchive &ar) { + if (ar.IsStoring()) { + // TODO: add storing code here + } + else { + // TODO: add loading code here + } +} + +#ifdef SHARED_HANDLERS + +// Support for thumbnails +void CScanlineRenderingDoc::OnDrawThumbnail(CDC &dc, LPRECT lprcBounds) { + // Modify this code to draw the document's data + dc.FillSolidRect(lprcBounds, RGB(255, 255, 255)); + + CString strText = _T("TODO: implement thumbnail drawing here"); + LOGFONT lf; + + CFont *pDefaultGUIFont = CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)); + pDefaultGUIFont->GetLogFont(&lf); + lf.lfHeight = 36; + + CFont fontDraw; + fontDraw.CreateFontIndirect(&lf); + + CFont *pOldFont = dc.SelectObject(&fontDraw); + dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK); + dc.SelectObject(pOldFont); +} + +// Support for Search Handlers +void CScanlineRenderingDoc::InitializeSearchContent() { + CString strSearchContent; + // Set search contents from document's data. + // The content parts should be separated by ";" + + // For example: strSearchContent = _T("point;rectangle;circle;ole object;"); + SetSearchContent(strSearchContent); +} + +void CScanlineRenderingDoc::SetSearchContent(const CString &value) { + if (value.IsEmpty()) { + RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid); + } + else { + CMFCFilterChunkValueImpl *pChunk = nullptr; + ATLTRY(pChunk = new CMFCFilterChunkValueImpl); + if (pChunk != nullptr) { + pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT); + SetChunkValue(pChunk); + } + } +} + +#endif // SHARED_HANDLERS + +// CScanlineRenderingDoc diagnostics + +#ifdef _DEBUG +void CScanlineRenderingDoc::AssertValid() const { + CDocument::AssertValid(); +} + +void CScanlineRenderingDoc::Dump(CDumpContext &dc) const { + CDocument::Dump(dc); +} +#endif //_DEBUG + +// CScanlineRenderingDoc commands diff --git a/ScanlineRendering/ScanlineRendering/ScanlineRenderingDoc.h b/ScanlineRendering/ScanlineRendering/ScanlineRenderingDoc.h new file mode 100644 index 0000000..184d11b --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/ScanlineRenderingDoc.h @@ -0,0 +1,42 @@ + +// ScanlineRenderingDoc.h : interface of the CScanlineRenderingDoc class +// + +#pragma once + +class CScanlineRenderingDoc : public CDocument { +protected: // create from serialization only + CScanlineRenderingDoc() noexcept; + DECLARE_DYNCREATE(CScanlineRenderingDoc) + + // Attributes +public: + // Operations +public: + // Overrides +public: + virtual BOOL OnNewDocument(); + virtual void Serialize(CArchive &ar); +#ifdef SHARED_HANDLERS + virtual void InitializeSearchContent(); + virtual void OnDrawThumbnail(CDC &dc, LPRECT lprcBounds); +#endif // SHARED_HANDLERS + + // Implementation +public: + virtual ~CScanlineRenderingDoc(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext &dc) const; +#endif + +protected: + // Generated message map functions +protected: + DECLARE_MESSAGE_MAP() + +#ifdef SHARED_HANDLERS + // Helper function that sets search content for a Search Handler + void SetSearchContent(const CString &value); +#endif // SHARED_HANDLERS +}; diff --git a/ScanlineRendering/ScanlineRendering/ScanlineRenderingView.cpp b/ScanlineRendering/ScanlineRendering/ScanlineRenderingView.cpp new file mode 100644 index 0000000..d94b192 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/ScanlineRenderingView.cpp @@ -0,0 +1,175 @@ + +// ScanlineRenderingView.cpp : implementation of the CScanlineRenderingView class +// + +#include "pch.h" +#include "framework.h" +// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail +// and search filter handlers and allows sharing of document code with that project. +#ifndef SHARED_HANDLERS +#include "ScanlineRendering.h" +#endif + +#include "ScanlineRenderingDoc.h" +#include "ScanlineRenderingView.h" +#include +#define Round(x) (int)(x + 0.5) + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +// CScanlineRenderingView + +IMPLEMENT_DYNCREATE(CScanlineRenderingView, CView) + +BEGIN_MESSAGE_MAP(CScanlineRenderingView, CView) +// Standard printing commands +// ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint) +// ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint) +// ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview) +ON_COMMAND(ID_FILE_PRINT, OnDrawpic) +END_MESSAGE_MAP() + +// CScanlineRenderingView construction/destruction + +CScanlineRenderingView::CScanlineRenderingView() noexcept { + // TODO: add construction code here +} + +CScanlineRenderingView::~CScanlineRenderingView() { +} + +BOOL CScanlineRenderingView::PreCreateWindow(CREATESTRUCT &cs) { + // TODO: Modify the Window class or styles here by modifying + // the CREATESTRUCT cs + + return CView::PreCreateWindow(cs); +} + +// CScanlineRenderingView drawing + +void CScanlineRenderingView::OnDraw(CDC * /*pDC*/) { + CScanlineRenderingDoc *pDoc = GetDocument(); + ASSERT_VALID(pDoc); + if (!pDoc) + return; + + DrawGraph(); +} + +// CScanlineRenderingView printing + +BOOL CScanlineRenderingView::OnPreparePrinting(CPrintInfo *pInfo) { + // default preparation + return DoPreparePrinting(pInfo); +} + +void CScanlineRenderingView::OnBeginPrinting(CDC * /*pDC*/, CPrintInfo * /*pInfo*/) { + // TODO: add extra initialization before printing +} + +void CScanlineRenderingView::OnEndPrinting(CDC * /*pDC*/, CPrintInfo * /*pInfo*/) { + // TODO: add cleanup after printing +} + +// CScanlineRenderingView diagnostics + +#ifdef _DEBUG +void CScanlineRenderingView::AssertValid() const { + CView::AssertValid(); +} + +void CScanlineRenderingView::Dump(CDumpContext &dc) const { + CView::Dump(dc); +} + +CScanlineRenderingDoc *CScanlineRenderingView::GetDocument() const // non-debug version is inline +{ + ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CScanlineRenderingDoc))); + return (CScanlineRenderingDoc *)m_pDocument; +} +#endif //_DEBUG + +// CScanlineRenderingView message handlers + +void CScanlineRenderingView::ReadPoint() { + P[0].x = 70; + P[0].y = 130; + P[0].c = C[0]; + P[1].x = -300; + P[1].y = -100; + P[1].c = C[1]; + P[2].x = 300; + P[2].y = -130; + P[2].c = C[2]; +} + +void CScanlineRenderingView::DrawGraph() { + CRect rect; + GetClientRect(&rect); + CDC *pDC = GetDC(); + pDC->SetMapMode(MM_ANISOTROPIC); + pDC->SetWindowExt(rect.Width(), rect.Height()); + pDC->SetViewportExt(rect.Width(), -rect.Height()); + pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2); + rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2); + if (!bFill) + DrawPolygon(pDC); + else + FillPolygon(pDC); + ReleaseDC(pDC); +} + +void CScanlineRenderingView::DrawPolygon(CDC *pDC) { + CLine *line = new CLine; + CP2 t; + for (int i = 0; i < 3; i++) { + if (i == 0) { + line->MoveTo(pDC, P[i]); + t = P[i]; + } + else { + line->LineTo(pDC, P[i]); + } + } + line->LineTo(pDC, t); + delete line; +} + +void CScanlineRenderingView::FillPolygon(CDC *pDC) { + ReadPoint(); + for (int i = 0; i < 3; i++) { + P1[i].x = P[i].x; + P1[i].y = Round(P[i].y); + P1[i].c = P[i].c; + } + CFill *fill = new CFill; + fill->SetPoint(P1, 3); + fill->CreateBucket(); + fill->CreateEdge(); + fill->Gouraud(pDC); + delete fill; +} + +void CScanlineRenderingView::OnDrawpic() { + for (int i = 0; i < 3; i++) { + COLORREF GetClr = RGB(0, 0, 0); + CColorDialog ccd(GetClr, CC_SOLIDCOLOR); + if (IDOK == ccd.DoModal()) + GetClr = ccd.GetColor(); + else + return; + C[i] = CRGB(GetRValue(GetClr) / 255.0, GetGValue(GetClr) / 255.0, GetBValue(GetClr) / 255.0); + } + + bFill = TRUE; + Invalidate(); +} + +void CScanlineRenderingView::OnInitialUpdate() { + CView::OnInitialUpdate(); + + bFill = FALSE; + ReadPoint(); +} diff --git a/ScanlineRendering/ScanlineRendering/ScanlineRenderingView.h b/ScanlineRendering/ScanlineRendering/ScanlineRenderingView.h new file mode 100644 index 0000000..5da715e --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/ScanlineRenderingView.h @@ -0,0 +1,59 @@ + +// ScanlineRenderingView.h : interface of the CScanlineRenderingView class +// + +#pragma once +#include "Line.h" +#include "Fill.h" + +class CScanlineRenderingView : public CView { +protected: // create from serialization only + CScanlineRenderingView() noexcept; + DECLARE_DYNCREATE(CScanlineRenderingView) + + // Attributes +public: + CScanlineRenderingDoc *GetDocument() const; + + // Operations +public: + void ReadPoint(); + void DrawGraph(); + void DrawPolygon(CDC *pDC); + void FillPolygon(CDC *pDC); + + // Overrides +public: + virtual void OnDraw(CDC *pDC); // overridden to draw this view + virtual BOOL PreCreateWindow(CREATESTRUCT &cs); + virtual void OnInitialUpdate(); + +protected: + virtual BOOL OnPreparePrinting(CPrintInfo *pInfo); + virtual void OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo); + virtual void OnEndPrinting(CDC *pDC, CPrintInfo *pInfo); + + // Implementation +public: + virtual ~CScanlineRenderingView(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext &dc) const; +#endif + +protected: + CP2 P[3]; + CPi2 P1[3]; + CRGB C[3]; + BOOL bFill; + +protected: + // Generated message map functions +protected: + afx_msg void OnDrawpic(); + DECLARE_MESSAGE_MAP() +}; + +#ifndef _DEBUG // debug version in ScanlineRenderingView.cpp +inline CScanlineRenderingDoc *CScanlineRenderingView::GetDocument() const { return reinterpret_cast(m_pDocument); } +#endif diff --git a/ScanlineRendering/ScanlineRendering/framework.h b/ScanlineRendering/ScanlineRendering/framework.h new file mode 100644 index 0000000..fb3b916 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/framework.h @@ -0,0 +1,36 @@ +#pragma once + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers +#endif + +#include "targetver.h" + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +// turns off MFC's hiding of some common and often safely ignored warning messages +#define _AFX_ALL_WARNINGS + +#include // MFC core and standard components +#include // MFC extensions + +#include // MFC Automation classes + +#ifndef _AFX_NO_OLE_SUPPORT +#include // MFC support for Internet Explorer 4 Common Controls +#endif +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include // MFC support for ribbons and control bars + +#ifdef _UNICODE +#if defined _M_IX86 +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif +#endif diff --git a/ScanlineRendering/ScanlineRendering/pch.cpp b/ScanlineRendering/ScanlineRendering/pch.cpp new file mode 100644 index 0000000..64b7eef --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/ScanlineRendering/ScanlineRendering/pch.h b/ScanlineRendering/ScanlineRendering/pch.h new file mode 100644 index 0000000..cc75712 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/pch.h @@ -0,0 +1,13 @@ +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +// add headers that you want to pre-compile here +#include "framework.h" + +#endif // PCH_H diff --git a/ScanlineRendering/ScanlineRendering/res/ScanlineRendering.ico b/ScanlineRendering/ScanlineRendering/res/ScanlineRendering.ico new file mode 100644 index 0000000..d56fbcd Binary files /dev/null and b/ScanlineRendering/ScanlineRendering/res/ScanlineRendering.ico differ diff --git a/ScanlineRendering/ScanlineRendering/res/ScanlineRendering.rc2 b/ScanlineRendering/ScanlineRendering/res/ScanlineRendering.rc2 new file mode 100644 index 0000000..7a18f98 Binary files /dev/null and b/ScanlineRendering/ScanlineRendering/res/ScanlineRendering.rc2 differ diff --git a/ScanlineRendering/ScanlineRendering/res/ScanlineRenderingDoc.ico b/ScanlineRendering/ScanlineRendering/res/ScanlineRenderingDoc.ico new file mode 100644 index 0000000..96365d4 Binary files /dev/null and b/ScanlineRendering/ScanlineRendering/res/ScanlineRenderingDoc.ico differ diff --git a/ScanlineRendering/ScanlineRendering/res/Toolbar.bmp b/ScanlineRendering/ScanlineRendering/res/Toolbar.bmp new file mode 100644 index 0000000..d501723 Binary files /dev/null and b/ScanlineRendering/ScanlineRendering/res/Toolbar.bmp differ diff --git a/ScanlineRendering/ScanlineRendering/targetver.h b/ScanlineRendering/ScanlineRendering/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/ScanlineRendering/ScanlineRendering/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include