#include "Rasteriser.h" Rasteriser app; bool Rasteriser::Initialise() { Model modelA; if (MD2Loader::LoadModel(".\\marvin.MD2", modelA, &Model::AddPolygon, &Model::AddVertex)) { _sceneModels.push_back(modelA); } else { return false; } _lights.push_back(new AmbientLight(150, 150, 150)); //_lights.push_back(new AmbientLight(255, 255, 255)); _lights.push_back(new DirectionalLight(Vector3D(-1, 0, -1), 150, 150, 150)); //_lights.push_back(new PointLight(Vertex(-10, 0, 10), 0, 1, 0, 100, 0, 0)); _cameras.push_back(Camera(0.0f, 0.0f, 0.0f, Vertex(0.0f, 0.0f, -50.0f))); _screenMinimized = false; return true; } void Rasteriser::SetCurrentCamera(int index) { if (index >= 0 && index < _cameras.size()) { _currentCamera = index; } } Camera& Rasteriser::GetCamera(int index) { return _cameras[index]; } Camera& Rasteriser::GetCurrentCamera() { return GetCamera(_currentCamera); } void Rasteriser::CalculateLighting(Model& currentModel, bool fullLightRender) { { for (int pi = 0; pi < currentModel.GetPolygonCount(); pi++) { if (!currentModel.GetPolygon(pi).GetCulled()) { if (fullLightRender) { for (int i = 0; i < currentModel.GetPolygon(pi).GetPolygonVertexCount(); i++) { COLORREF colorWorking = RGB(0, 0, 0); for (Light* currentLight : _lights) { colorWorking = currentLight->CalculateLight(currentModel, currentModel.GetVertex(pi, i), colorWorking); } currentModel.SetVertexColor(pi, i, colorWorking); } } else { COLORREF colorWorking = RGB(0, 0, 0); for (Light* currentLight : _lights) { colorWorking = currentLight->CalculateLight(currentModel, currentModel.GetPolygon(pi), colorWorking); } currentModel.SetPolygonColor(pi, colorWorking); } } } } } void Rasteriser::Update(const Bitmap& bitmap) { if (bitmap.GetWidth() == 0 || bitmap.GetHeight() == 0) { _screenMinimized = true; } else { _screenMinimized = false; } if (!_screenMinimized) { int currentRot = (_rotation % 360); Vertex startPos = Vertex(0, 0, 20); int currentZOff = 0; int currentModelIndex = 0; for (Model& currentModel : _sceneModels) { currentModel.EnqueueTransform(GetTranslateMatrix(startPos)); currentModel.EnqueueTransform(GetRotationMatrix(Axis::Y, (float)currentRot)); //startPos.SetX(startPos.GetX() + 100); if ((currentModelIndex % 2) == 1) { currentZOff = 0; } else { currentZOff = 100; } //startPos.SetZ((float)currentZOff); currentModelIndex++; } _currentAspectRatio = (float)(bitmap.GetWidth() / (float)bitmap.GetHeight()); _currentPerspectiveMatrix = GetPerspectiveProjectionMatrix(1, _currentAspectRatio); _currentViewMatrix = GetViewMatrix(1, bitmap.GetWidth(), bitmap.GetHeight()); if (_rotation == 360) { _rotation = 0; } else { _rotation += 1; } } } void Rasteriser::Render(const Bitmap& bitmap) { if (!_screenMinimized) { ClearViewport(bitmap); SelectObject(bitmap.GetDC(), GetStockObject(DC_BRUSH)); SelectObject(bitmap.GetDC(), GetStockObject(DC_PEN)); for (Model& currentModel : _sceneModels) { currentModel.SetReflectionCoefficient(0.5f, 0.5f, 0.5f); Matrix workingMatrix = workingMatrix.IdentityMatrix(); for (Matrix currentTransform : currentModel.GetPendingTransforms()) { workingMatrix *= currentTransform; } currentModel.ApplyTransformToLocalVertices(workingMatrix); currentModel.ApplyTransformToTransformedVertices(GetCurrentCamera().GetCurrentCameraTransformMatrix()); currentModel.CalculateBackfaces(GetCurrentCamera()); currentModel.Sort(); currentModel.CalculateVertexNormals(); CalculateLighting(currentModel, true); currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix); currentModel.DehomogenizeAllVertices(); currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix); //DrawWireFrame(bitmap.GetDC(), currentModel); //DrawSolidFlat(bitmap.GetDC(), currentModel); //DrawRasterisedSolidFlat(bitmap.GetDC(), currentModel); DrawGouraud(bitmap.GetDC(), currentModel); currentModel.ClearPendingTransforms(); } } } void Rasteriser::ClearViewport(const Bitmap& bitmap) { bitmap.Clear(RGB(0, 0, 0)); } void Rasteriser::DrawSquare(HDC hDc, const vector verticies) { POINT pointArray[4]; for (int i = 0; i < 4; i++) { pointArray[i].x = (long) verticies[i].GetX(); pointArray[i].y = (long) verticies[i].GetY(); } SetDCBrushColor(hDc, RGB(255, 0, 255)); SetDCPenColor(hDc, RGB(0, 0, 255)); Polygon(hDc, pointArray, 4); } void Rasteriser::DrawShape(HDC hDc, const vector verticies) { vector pointArray; for (int i = 0; i < verticies.size(); i++) { POINT newPoint; newPoint.x = (long)verticies[i].GetX(); newPoint.y = (long)verticies[i].GetY(); pointArray.push_back(newPoint); } SetDCBrushColor(hDc, RGB(rand() % 256, rand() % 256, rand() % 256)); SetDCPenColor(hDc, RGB(rand() % 256, rand() % 256, rand() % 256)); Polygon(hDc, pointArray.data(), (int) verticies.size()); } void Rasteriser::DrawWireFrame(HDC hDc, Model& model) { vector pointArray; vector sizeArray; int unculledPolyCount = 0; int modelPolygonCount = (int) model.GetPolygonCount(); for (int i = 0; i < modelPolygonCount; i++) { if (!model.GetPolygon(i).GetCulled()) { int currentPolygonVertexCount = (int)model.GetPolygon(i).GetPolygonVertexCount(); for (int j = 0; j < currentPolygonVertexCount; j++) { POINT newPoint; newPoint.x = (long)model.GetVertex(i, j).GetX(); newPoint.y = (long)model.GetVertex(i, j).GetY(); pointArray.push_back(newPoint); } sizeArray.push_back(currentPolygonVertexCount); unculledPolyCount++; } } PolyPolygon(hDc, pointArray.data(), sizeArray.data(), unculledPolyCount); } void Rasteriser::DrawSolidFlat(HDC hDc, Model& model) { int modelPolygonCount = (int)model.GetPolygonCount(); for (int i = 0; i < modelPolygonCount; i++) { if (!model.GetPolygon(i).GetCulled()) { vector pointArray; int currentPolygonVertexCount = (int)model.GetPolygon(i).GetPolygonVertexCount(); for (int j = 0; j < currentPolygonVertexCount; j++) { POINT newPoint; newPoint.x = (long)model.GetVertex(i, j).GetX(); newPoint.y = (long)model.GetVertex(i, j).GetY(); pointArray.push_back(newPoint); } SetDCBrushColor(hDc, model.GetPolygon(i).GetColor()); SetDCPenColor(hDc, model.GetPolygon(i).GetColor()); Polygon(hDc, pointArray.data(), currentPolygonVertexCount); } } } void Rasteriser::DrawRasterisedSolidFlat(HDC hDc, Model& model) { int modelPolygonCount = (int)model.GetPolygonCount(); for (int i = 0; i < modelPolygonCount; i++) { if (!model.GetPolygon(i).GetCulled()) { vector vertexArray = model.GetPolygonVertexArray(i); FillPolygonFlat(hDc, vertexArray, model.GetPolygon(i).GetColor()); } } } void Rasteriser::DrawGouraud(HDC hDc, Model& model) { int modelPolygonCount = (int)model.GetPolygonCount(); for (int i = 0; i < modelPolygonCount; i++) { if (!model.GetPolygon(i).GetCulled()) { vector vertexArray = model.GetPolygonVertexArray(i); FillPolygonGouraud(hDc, vertexArray); } } } bool VerticiesYCompareAsc(Vertex& v1, Vertex& v2) { return v1.GetY() < v2.GetY(); } void Rasteriser::FillPolygonFlat(HDC hDc, vector& verts, COLORREF colorIn) { sort(verts.begin(), verts.end(), VerticiesYCompareAsc); if (verts[1].GetY() == verts[2].GetY()) { FillFlatSideTriangle(hDc, verts[0], verts[1], verts[2], colorIn); } else if (verts[0].GetY() == verts[1].GetY()) { FillFlatSideTriangle(hDc, verts[2], verts[0], verts[1], colorIn); } else { Vertex temp = Vertex(verts[0].GetX() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetX() - verts[0].GetX()), verts[1].GetY(), verts[1].GetZ()); if (verts[1].GetX() < temp.GetX()) { FillFlatSideTriangle(hDc, verts[0], verts[1], temp, colorIn); FillFlatSideTriangle(hDc, verts[2], verts[1], temp, colorIn); } else { FillFlatSideTriangle(hDc, verts[0], temp, verts[1], colorIn); FillFlatSideTriangle(hDc, verts[2], temp, verts[1], colorIn); } } } void Rasteriser::FillFlatSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3, COLORREF colorIn) { Vertex tempA = Vertex(v1); Vertex tempB = Vertex(v1); bool changed1 = false; bool changed2 = false; int dx1 = (int)ceil(abs(v2.GetX() - v1.GetX())); int dy1 = (int)ceil(abs(v2.GetY() - v1.GetY())); int dx2 = (int)ceil(abs(v3.GetX() - v1.GetX())); int dy2 = (int)ceil(abs(v3.GetY() - v1.GetY())); int signx1 = (int)sgn(v2.GetX() - v1.GetX()); int signx2 = (int)sgn(v3.GetX() - v1.GetX()); int signy1 = (int)sgn(v2.GetY() - v1.GetY()); int signy2 = (int)sgn(v3.GetY() - v1.GetY()); if (dy1 > dx1) { int tempInt = dx1; dx1 = dy1; dy1 = tempInt; changed1 = true; } if (dy2 > dx2) { int tempInt = dx2; dx2 = dy2; dy2 = tempInt; changed2 = true; } int e1 = 2 * dy1 - dx1; int e2 = 2 * dy2 - dx2; for (int i = 0; i <= dx1; i++) { int startPoint; int endPoint; if (tempA.GetXInt() < tempB.GetXInt()) { startPoint = tempA.GetXInt(); endPoint = tempB.GetXInt(); } else { startPoint = tempB.GetXInt(); endPoint = tempA.GetXInt(); } for (int xi = (int)ceil(startPoint); xi <= endPoint; xi++) { SetPixel(hDc, xi, tempA.GetYInt(), colorIn); } while (e1 >= 0) { if (changed1) { tempA.SetX(tempA.GetX() + signx1); } else { tempA.SetY(tempA.GetY() + signy1); } e1 = e1 - 2 * dx1; } if (changed1) { tempA.SetY(tempA.GetY() + signy1); } else { tempA.SetX(tempA.GetX() + signx1); } e1 = e1 + 2 * dy1; while (tempB.GetY() != tempA.GetY()) { while (e2 >= 0) { if (changed2) { tempB.SetX(tempB.GetX() + signx2); } else { tempB.SetY(tempB.GetY() + signy2); } e2 = e2 - 2 * dx2; } if (changed2) { tempB.SetY(tempB.GetY() + signy2); } else { tempB.SetX(tempB.GetX() + signx2); } e2 = e2 + 2 * dy2; } } } void Rasteriser::FillPolygonGouraud(HDC hDc, vector& verts) { sort(verts.begin(), verts.end(), VerticiesYCompareAsc); if (verts[1].GetY() == verts[2].GetY()) { FillGouraudBottomFlatTriangle(hDc, verts[0], verts[1], verts[2]); } else if (verts[0].GetY() == verts[1].GetY()) { FillGouraudTopFlatTriangle(hDc, verts[0], verts[1], verts[2]); } else { Vertex temp = Vertex(verts[0].GetX() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetX() - verts[0].GetX()), verts[1].GetY(), verts[1].GetZ()); temp.SetNormal(verts[1].GetNormal()); float cRed = GetRValue(verts[0].GetColor()) + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (GetRValue(verts[2].GetColor()) - GetRValue(verts[0].GetColor())); float cGreen = GetGValue(verts[0].GetColor()) + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (GetGValue(verts[2].GetColor()) - GetGValue(verts[0].GetColor())); float cBlue = GetBValue(verts[0].GetColor()) + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (GetBValue(verts[2].GetColor()) - GetBValue(verts[0].GetColor())); temp.SetColor(RGB((int)cRed, (int)cGreen, (int)cBlue)); temp.SetColor(verts[1].GetColor()); FillGouraudBottomFlatTriangle(hDc, verts[0], verts[1], temp); FillGouraudTopFlatTriangle(hDc, verts[1], temp, verts[2]); } } void Rasteriser::FillGouraudBottomFlatTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3) { float slope1 = (float)(v2.GetX() - v1.GetX()) / (float)(v2.GetY() - v1.GetY()); float slope2 = (float)(v3.GetX() - v1.GetX()) / (float)(v3.GetY() - v1.GetY()); float x1 = (float)v1.GetX(); float x2 = (float)v1.GetX() + 0.5f; if (slope2 < slope1) { float slopeTmp = slope1; slope1 = slope2; slope2 = slopeTmp; } for (int scanlineY = (int)v1.GetY(); scanlineY <= (int)v2.GetY(); scanlineY++) { float iRedA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetR() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetR(); float iRedB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetR() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetR(); float iGreenA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetG() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetG(); float iGreenB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetG() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetG(); float iBlueA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetB() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetB(); float iBlueB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetB() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetB(); for (int xi = (int)ceil(x1); xi < (int)x2; xi++) { float redTmp = (x2 - xi) / (x2 - x1) * iRedA + (xi - x1) / (x2 - x1) * iRedB; float greenTmp = (x2 - xi) / (x2 - x1) * iGreenA + (xi - x1) / (x2 - x1) * iGreenB; float blueTmp = (x2 - xi) / (x2 - x1) * iBlueA + (xi - x1) / (x2 - x1) * iBlueB; COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)redTmp), BoundsCheck(0, 255, (int)greenTmp), BoundsCheck(0, 255, (int)blueTmp)); SetPixel(hDc, xi, scanlineY, currentColor); } x1 += slope1; x2 += slope2; } } void Rasteriser::FillGouraudTopFlatTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3) { float slope1 = (float)(v3.GetX() - v1.GetX()) / (float)(v3.GetY() - v1.GetY()); float slope2 = (float)(v3.GetX() - v2.GetX()) / (float)(v3.GetY() - v2.GetY()); float x1 = (float)v3.GetX(); float x2 = (float)v3.GetX() + 0.5f; if (slope1 < slope2) { float slopeTmp = slope1; slope1 = slope2; slope2 = slopeTmp; } for (int scanlineY = (int)v3.GetY(); scanlineY > (int)v1.GetY(); scanlineY--) { float iRedA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetR() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetR(); float iRedB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetR() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetR(); float iGreenA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetG() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetG(); float iGreenB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetG() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetG(); float iBlueA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetB() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetB(); float iBlueB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetB() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetB(); for (int xi = (int)ceil(x1); xi < (int)x2; xi++) { float redTmp = (x2 - xi) / (x2 - x1) * iRedA - (xi - x1) / (x2 - x1) * iRedB; float greenTmp = (x2 - xi) / (x2 - x1) * iGreenA - (xi - x1) / (x2 - x1) * iGreenB; float blueTmp = (x2 - xi) / (x2 - x1) * iBlueA - (xi - x1) / (x2 - x1) * iBlueB; COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)redTmp), BoundsCheck(0, 255, (int)greenTmp), BoundsCheck(0, 255, (int)blueTmp)); SetPixel(hDc, xi, scanlineY, currentColor); } x1 -= slope1; x2 -= slope2; } } void Rasteriser::FillPolygonGouraudInt(HDC hDc, vector& verts) { sort(verts.begin(), verts.end(), VerticiesYCompareAsc); if (verts[1].GetY() == verts[2].GetY()) { FillGouraudSideTriangle(hDc, verts[0], verts[1], verts[2]); } else if (verts[0].GetY() == verts[1].GetY()) { FillGouraudSideTriangle(hDc, verts[2], verts[0], verts[1]); } else { Vertex temp = Vertex(verts[0].GetX() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetX() - verts[0].GetX()), verts[1].GetY(), verts[1].GetZ()); temp.SetNormal(verts[1].GetNormal()); float cRed = verts[0].GetR() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetR() - verts[0].GetR()); float cGreen = verts[0].GetG() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetG() - verts[0].GetG()); float cBlue = verts[0].GetB() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetB() - verts[0].GetB()); temp.SetColor(BoundsCheck(0, 255, (int)cRed), BoundsCheck(0, 255, (int)cGreen), BoundsCheck(0, 255, (int)cBlue)); if (verts[1].GetX() < temp.GetX()) { FillGouraudSideTriangle(hDc, verts[0], verts[1], temp); FillGouraudSideTriangle(hDc, verts[2], verts[1], temp); } else { FillGouraudSideTriangle(hDc, verts[0], temp, verts[1]); FillGouraudSideTriangle(hDc, verts[2], temp, verts[1]); } } } void Rasteriser::FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3) { Vertex tempA = Vertex(v1); Vertex tempB = Vertex(v1); bool changed1 = false; bool changed2 = false; int dx1 = (int)ceil(abs(v2.GetX() - v1.GetX())); int dy1 = (int)ceil(abs(v2.GetY() - v1.GetY())); int dx2 = (int)ceil(abs(v3.GetX() - v1.GetX())); int dy2 = (int)ceil(abs(v3.GetY() - v1.GetY())); int signx1 = (int)ceil(sgn(v2.GetX() - v1.GetX())); int signx2 = (int)ceil(sgn(v3.GetX() - v1.GetX())); int signy1 = (int)ceil(sgn(v2.GetY() - v1.GetY())); int signy2 = (int)ceil(sgn(v3.GetY() - v1.GetY())); if (dy1 > dx1) { int tempDx = dx1; dx1 = dy1; dy1 = tempDx; changed1 = true; } if (dy2 > dx2) { int tempDx = dx2; dx2 = dy2; dy2 = tempDx; changed2 = true; } int e1 = 2 * (int)dy1 - (int)dx1; int e2 = 2 * (int)dy2 - (int)dx2; for (int i = 0; i <= (int)dx1; i++) { float leftEndPoint; float rightEndPoint; if (tempA.GetX() < tempB.GetX()) { leftEndPoint = tempA.GetX(); rightEndPoint = tempB.GetX(); } else { leftEndPoint = tempB.GetX(); rightEndPoint = tempA.GetX(); } float iRedA = (tempA.GetY() - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetR() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v2.GetY()) * v2.GetR(); float iRedB = (tempA.GetY() - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetR() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v3.GetY()) * v3.GetR(); float iGreenA = (tempA.GetY() - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetG() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v2.GetY()) * v2.GetG(); float iGreenB = (tempA.GetY() - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetG() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v3.GetY()) * v3.GetG(); float iBlueA = (tempA.GetY() - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetB() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v2.GetY()) * v2.GetB(); float iBlueB = (tempA.GetY() - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetB() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v3.GetY()) * v3.GetB(); for (int xi = (int)ceil(leftEndPoint); xi <= (int)rightEndPoint; xi++) { float redTmp = (rightEndPoint - xi) / (rightEndPoint - leftEndPoint) * iRedA + (xi - leftEndPoint) / (rightEndPoint - leftEndPoint) * iRedB; float greenTmp = (rightEndPoint - xi) / (rightEndPoint - leftEndPoint) * iGreenA + (xi - leftEndPoint) / (rightEndPoint - leftEndPoint) * iGreenB; float blueTmp = (rightEndPoint - xi) / (rightEndPoint - leftEndPoint) * iBlueA + (xi - leftEndPoint) / (rightEndPoint - leftEndPoint) * iBlueB; COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)redTmp), BoundsCheck(0, 255, (int)greenTmp), BoundsCheck(0, 255, (int)blueTmp)); SetPixel(hDc, xi, tempA.GetYInt(), currentColor); } while (e1 >= 0) { if (changed1) { tempA.SetX((float)tempA.GetXInt() + (float)signx1); } else { tempA.SetY((float)tempA.GetYInt() + (float)signy1); } e1 = e1 - 2 * dx1; } if (changed1) { tempA.SetY((float)tempA.GetYInt() + (float)signy1); } else { tempA.SetX((float)tempA.GetXInt() + (float)signx1); } e1 = e1 + 2 * dy1; while (tempB.GetY() < tempA.GetY() && tempB.GetY() > tempA.GetY()) { while (e2 >= 0) { if (changed2) { tempB.SetX((float)tempB.GetXInt() + (float)signx2); } else { tempB.SetY((float)tempB.GetYInt() + (float)signy2); } e2 = e2 - 2 * dx2; } if (changed2) { tempB.SetY((float)tempB.GetYInt() + (float)signy2); } else { tempB.SetX((float)tempB.GetXInt() + (float)signx2); } e2 = e2 + 2 * dy2; } } }