aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateja <mail@matejamaric.com>2020-08-18 11:41:26 +0200
committerMateja <mail@matejamaric.com>2020-08-18 11:41:26 +0200
commit79c65ab0852ca6b1dc023505c5026cbf96e06d0f (patch)
treeb4c2945b1008d6919a4f89d3759bd89c7c8db671
downloadscanline-render-79c65ab0852ca6b1dc023505c5026cbf96e06d0f.tar.gz
scanline-render-79c65ab0852ca6b1dc023505c5026cbf96e06d0f.zip
first commit
-rw-r--r--.gitignore2
-rwxr-xr-xmain.cpp162
-rw-r--r--makefile11
3 files changed, 175 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ae07e71
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.ppm
+render
diff --git a/main.cpp b/main.cpp
new file mode 100755
index 0000000..9b1ce8c
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,162 @@
+#include<fstream>
+#include<cmath>
+
+class Vertice
+{
+public:
+ float x, y, z;
+ unsigned char red, green, blue;
+ Vertice(float x, float y, float z, int red, int green, int blue)
+ {
+ this->x = x;
+ this->y = y;
+ this->z = z;
+
+ this->red = (unsigned char)red;
+ this->green = (unsigned char)green;
+ this->blue = (unsigned char)blue;
+ }
+ void fitToImage(int imageWidth, int imageHeight)
+ {
+ x = (x * (imageWidth / 2)) + (imageWidth / 2);
+ y = (-y * (imageHeight / 2)) + (imageHeight / 2);
+ }
+};
+
+class Image
+{
+public:
+ int imageWidth, imageHeight;
+ unsigned char* pixels;
+ Image(int imageWidth, int imageHeight)
+ {
+ this->imageWidth = imageWidth;
+ this->imageHeight = imageHeight;
+ pixels = new unsigned char[imageWidth * imageHeight * 3];
+ }
+ ~Image()
+ {
+ delete[] pixels;
+ }
+ void setPixel(int x, int y, int red, int green, int blue)
+ {
+ int help_var = ((y * imageWidth) + x) * 3;
+ pixels[help_var + 0] = (unsigned char)red;
+ pixels[help_var + 1] = (unsigned char)green;
+ pixels[help_var + 2] = (unsigned char)blue;
+ }
+ void fillPixels(int red, int green, int blue)
+ {
+ int help_var = imageWidth * imageHeight * 3;
+ for (int i = 0; i < help_var; i += 3) {
+ pixels[i + 0] = (unsigned char)red;
+ pixels[i + 1] = (unsigned char)green;
+ pixels[i + 2] = (unsigned char)blue;
+ }
+ }
+ //-------------------SCANLINE TRIANGLE RASTERISATION---------------------------
+ void fillFlatTopTriangle(Vertice* v1, Vertice* v2, Vertice* v3)
+ {
+ float invslope1 = (float)(v3->x - v1->x) / (float)(v3->y - v1->y);
+ float invslope2 = (float)(v3->x - v2->x) / (float)(v3->y - v2->y);
+
+ float curx1 = v3->x;
+ float curx2 = v3->x;
+ int cury1 = (int)ceil(v1->y - 0.5f);
+ int cury2 = (int)ceil(v3->y - 0.5f);
+
+ for (int i = cury2; i >= cury1; i--)
+ {
+ if(curx1 < curx2)
+ for (int j = (int)ceil(curx1 - 0.5f); j <= (int)ceil(curx2 - 0.5f); j++)
+ setPixel(j, i, 255, 0, 0);
+ else
+ for (int j = (int)ceil(curx2 - 0.5f); j <= (int)ceil(curx1 - 0.5f); j++)
+ setPixel(j, i, 255, 0, 0);
+
+ curx1 -= invslope1;
+ curx2 -= invslope2;
+ }
+ }
+ void fillFlatBottomTriangle(Vertice* v1, Vertice* v2, Vertice* v3)
+ {
+ float invslope1 = (float)(v2->x - v1->x) / (float)(v2->y - v1->y);
+ float invslope2 = (float)(v3->x - v1->x) / (float)(v3->y - v1->y);
+
+ float curx1 = v1->x;
+ float curx2 = v1->x;
+ int cury1 = (int)ceil(v1->y - 0.5f);
+ int cury2 = (int)ceil(v2->y - 0.5f);
+ for (int i = cury1; i <= cury2; i++)
+ {
+ if(curx1 < curx2)
+ for (int j = (int)ceil(curx1 - 0.5f); j <= (int)ceil(curx2 - 0.5f); j++)
+ setPixel(j, i, 255, 0, 0);
+ else
+ for (int j = (int)ceil(curx2 - 0.5f); j <= (int)ceil(curx1 - 0.5f); j++)
+ setPixel(j, i, 255, 0, 0);
+
+ curx1 += invslope1;
+ curx2 += invslope2;
+ }
+ }
+ void fillTriangle(Vertice* v1, Vertice* v2, Vertice* v3)
+ {
+ if (v1->y > v2->y)
+ std::swap(v1, v2);
+ if (v1->y > v3->y)
+ std::swap(v1, v3);
+ if (v2->y > v3->y)
+ std::swap(v2, v3);
+
+ if (v2->y == v3->y){
+ if(v2->x < v3->x)
+ std::swap(v2, v3);
+ fillFlatBottomTriangle(v1, v2, v3);
+ }
+ else if (v1->y == v2->y){
+ if(v1->x < v2->x)
+ std::swap(v1, v2);
+ fillFlatTopTriangle(v1, v2, v3);
+ }
+ else
+ {
+ Vertice v4(
+ (v1->x + (((float)(v2->y - v1->y) / (float)(v3->y - v1->y)) * (v3->x - v1->x))), v2->y, 0.0f, 0, 0, 0);
+ if(v1->x < v4.x){
+ fillFlatBottomTriangle(v1, v2, &v4);
+ fillFlatTopTriangle(v2, &v4, v3);
+ }
+ else{
+ fillFlatBottomTriangle(v1, &v4, v2);
+ fillFlatTopTriangle(&v4, v2, v3);
+ }
+ }
+
+ }
+ //-----------------------------------------------------------------------------
+};
+
+int main()
+{
+ Image image(800, 600);
+ image.fillPixels(255, 255, 255);
+
+ Vertice a(0.2f, 0.5f, 0.0f, 255, 0, 0);
+ Vertice b(-0.5f, 0.0f, 0.0f, 0, 255, 0);
+ Vertice c(0.5f, -0.5f, 0.0f, 0, 0, 255);
+
+ a.fitToImage(image.imageWidth, image.imageHeight);
+ b.fitToImage(image.imageWidth, image.imageHeight);
+ c.fitToImage(image.imageWidth, image.imageHeight);
+
+ image.fillTriangle(&a, &b, &c);
+
+ std::ofstream imageFile;
+ imageFile.open("./image.ppm");
+ imageFile << "P6\n" << image.imageWidth << " " << image.imageHeight << "\n255\n";
+ imageFile.write((char*)image.pixels, image.imageWidth * image.imageHeight * 3);
+ imageFile.close();
+
+ return 0;
+}
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..0a4fca9
--- /dev/null
+++ b/makefile
@@ -0,0 +1,11 @@
+render: main.cpp
+ g++ -o render main.cpp
+image.ppm: render
+ ./render
+run: render
+ ./render
+view: image.ppm
+ feh -. image.ppm
+clean:
+ rm image.ppm
+ rm render