diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/Bitmap.cpp | 34 | ||||
| -rw-r--r-- | source/Bitmap.h | 12 | ||||
| -rw-r--r-- | source/Matrix4f.cpp | 104 | ||||
| -rw-r--r-- | source/Matrix4f.h | 15 | ||||
| -rw-r--r-- | source/ObjModel.cpp | 93 | ||||
| -rw-r--r-- | source/ObjModel.h | 31 | ||||
| -rw-r--r-- | source/Render.cpp | 98 | ||||
| -rw-r--r-- | source/Render.h | 13 | ||||
| -rw-r--r-- | source/Vector4f.cpp | 32 | ||||
| -rw-r--r-- | source/Vector4f.h | 12 | ||||
| -rw-r--r-- | source/Vertice.cpp | 46 | ||||
| -rw-r--r-- | source/Vertice.h | 14 | ||||
| -rw-r--r-- | source/main.cpp | 83 | 
13 files changed, 587 insertions, 0 deletions
| diff --git a/source/Bitmap.cpp b/source/Bitmap.cpp new file mode 100644 index 0000000..363145f --- /dev/null +++ b/source/Bitmap.cpp @@ -0,0 +1,34 @@ +#include "Bitmap.h"
 +
 +Bitmap::Bitmap(int width_, int height_) {
 +	width = width_;
 +	height = height_;
 +	pixels = new unsigned char[width * height * 4];
 +}
 +
 +Bitmap::~Bitmap() {
 +	delete[] pixels;
 +}
 +
 +void Bitmap::fill(int r, int g, int b) {
 +	for (int i = 0; i < width * height * 4; i+=4)
 +	{
 +		pixels[i + 0] = r;
 +		pixels[i + 1] = g;
 +		pixels[i + 2] = b;
 +		pixels[i + 3] = 255;
 +	}
 +}
 +
 +void Bitmap::setPixel(int x, int y, int r, int g, int b) {
 +	int hlp = ((y * width) + x) * 4;
 +	if (!(hlp < 0 || hlp >(width * height * 4) - 3)) {
 +		pixels[hlp + 0] = r;
 +		pixels[hlp + 1] = g;
 +		pixels[hlp + 2] = b;
 +		pixels[hlp + 3] = 255;
 +	}
 +	else {
 +		std::cout << "Position of pixel:\t" << hlp << "\tX: " << x << "\tY: "<< y << "\n";
 +	}
 +}
 diff --git a/source/Bitmap.h b/source/Bitmap.h new file mode 100644 index 0000000..c4064ad --- /dev/null +++ b/source/Bitmap.h @@ -0,0 +1,12 @@ +#include<iostream>
 +class Bitmap
 +{
 +public:
 +	int width, height;
 +	unsigned char *pixels;
 +	Bitmap(int width_, int height_);
 +	~Bitmap();
 +	void fill(int r, int g, int b);
 +	void setPixel(int x,  int y, int r, int g, int b);
 +};
 +
 diff --git a/source/Matrix4f.cpp b/source/Matrix4f.cpp new file mode 100644 index 0000000..c8be036 --- /dev/null +++ b/source/Matrix4f.cpp @@ -0,0 +1,104 @@ +#include "Matrix4f.h"
 +
 +
 +
 +Matrix4f::Matrix4f()
 +{
 +	m[0][0] = 1;	m[0][1] = 0;	m[0][2] = 0;	m[0][3] = 0;
 +	m[1][0] = 0;	m[1][1] = 1;	m[1][2] = 0;	m[1][3] = 0;
 +	m[2][0] = 0;	m[2][1] = 0;	m[2][2] = 1;	m[2][3] = 0;
 +	m[3][0] = 0;	m[3][1] = 0;	m[3][2] = 0;	m[3][3] = 1;
 +}
 +
 +Matrix4f Matrix4f::multiply(Matrix4f& a)
 +{
 +	Matrix4f b = identity();
 +	for (int i = 0; i < 4; i++)
 +	{
 +		for (int j = 0; j < 4; j++)
 +		{
 +			b.m[i][j] = ((m[i][0] * a.m[0][j]) + (m[i][1] * a.m[1][j]) + (m[i][2] * a.m[2][j]) + (m[i][3] * a.m[3][j]));
 +		}
 +	}
 +	return b;
 +}
 +
 +Matrix4f Matrix4f::operator*(Matrix4f& a)
 +{
 +	Matrix4f b = identity();
 +	for (int i = 0; i < 4; i++)
 +	{
 +		for (int j = 0; j < 4; j++)
 +		{
 +			b.m[i][j] = ((m[i][0] * a.m[0][j]) + (m[i][1] * a.m[1][j]) + (m[i][2] * a.m[2][j]) + (m[i][3] * a.m[3][j]));
 +		}
 +	}
 +	return b;
 +}
 +
 +Matrix4f Matrix4f::identity()
 +{
 +	return Matrix4f();
 +}
 +
 +Matrix4f Matrix4f::move(float kx, float ky, float kz)
 +{
 +	Matrix4f b;
 +	b.m[0][0] = 1;	b.m[0][1] = 0;	b.m[0][2] = 0;	b.m[0][3] = kx;
 +	b.m[1][0] = 0;	b.m[1][1] = 1;	b.m[1][2] = 0;	b.m[1][3] = ky;
 +	b.m[2][0] = 0;	b.m[2][1] = 0;	b.m[2][2] = 1;	b.m[2][3] = kz;
 +	b.m[3][0] = 0;	b.m[3][1] = 0;	b.m[3][2] = 0;	b.m[3][3] = 1;
 +	return b;
 +}
 +
 +Matrix4f Matrix4f::rotate(float xs, float ys, float zs)
 +{
 +	double hlp = 3.14159265 / 180.0;
 +	xs *= hlp;
 +	ys *= hlp;
 +	zs *= hlp;
 +	Matrix4f b;
 +	b.m[0][0] = 1;	b.m[0][1] = 0;			b.m[0][2] = 0;			b.m[0][3] = 0;
 +	b.m[1][0] = 0;	b.m[1][1] = cos(xs);	b.m[1][2] = -sin(xs);	b.m[1][3] = 0;
 +	b.m[2][0] = 0;	b.m[2][1] = sin(xs);	b.m[2][2] = cos(xs);	b.m[2][3] = 0;
 +	b.m[3][0] = 0;	b.m[3][1] = 0;			b.m[3][2] = 0;			b.m[3][3] = 1;
 +
 +	Matrix4f c;
 +	c.m[0][0] = cos(ys);	c.m[0][1] = 0;	c.m[0][2] = sin(ys);	c.m[0][3] = 0;
 +	c.m[1][0] = 0;			c.m[1][1] = 1;	c.m[1][2] = 0;			c.m[1][3] = 0;
 +	c.m[2][0] = -sin(ys);	c.m[2][1] = 0;	c.m[2][2] = cos(ys);	c.m[2][3] = 0;
 +	c.m[3][0] = 0;			c.m[3][1] = 0;	c.m[3][2] = 0;			c.m[3][3] = 1;
 +
 +	Matrix4f d;
 +	d.m[0][0] = cos(zs);	d.m[0][1] = -sin(zs);	d.m[0][2] = 0;	d.m[0][3] = 0;
 +	d.m[1][0] = sin(zs);	d.m[1][1] = cos(zs);	d.m[1][2] = 0;	d.m[1][3] = 0;
 +	d.m[2][0] = 0;			d.m[2][1] = 0;			d.m[2][2] = 1;	d.m[2][3] = 0;
 +	d.m[3][0] = 0;			d.m[3][1] = 0;			d.m[3][2] = 0;	d.m[3][3] = 1;
 +
 +	return d * c * b;
 +}
 +
 +Matrix4f Matrix4f::scale(float px, float py, float pz)
 +{
 +	Matrix4f b;
 +	b.m[0][0] = px;	b.m[0][1] = 0;	b.m[0][2] = 0;	b.m[0][3] = 0;
 +	b.m[1][0] = 0;	b.m[1][1] = py;	b.m[1][2] = 0;	b.m[1][3] = 0;
 +	b.m[2][0] = 0;	b.m[2][1] = 0;	b.m[2][2] = pz;	b.m[2][3] = 0;
 +	b.m[3][0] = 0;	b.m[3][1] = 0;	b.m[3][2] = 0;	b.m[3][3] = 1;
 +	return b;
 +}
 +
 +Matrix4f Matrix4f::perspective(float n, float f, float fov, float aspectRatio)
 +{
 +	float l, r, t, b;
 +	t = n * tan((fov / 2.0f) * (3.14159265 / 180.0));
 +	b = -t;
 +	r = aspectRatio * t;
 +	l = -r;
 +	Matrix4f a;
 +	a.m[0][0] = ((2.0f * n) / (r - l));	a.m[0][1] = 0;						a.m[0][2] = - ((r + l) / (r - l));	a.m[0][3] = 0;
 +	a.m[1][0] = 0;						a.m[1][1] = ((2.0f * n) / (t - b));	a.m[1][2] = - ((t + b) / (t - b));	a.m[1][3] = 0;
 +	a.m[2][0] = 0;						a.m[2][1] = 0;						a.m[2][2] = - (f / (n - f));		a.m[2][3] = ((n * f) / (n - f));
 +	a.m[3][0] = 0;						a.m[3][1] = 0;						a.m[3][2] = 1;						a.m[3][3] = 0;
 +	return a;
 +}
 diff --git a/source/Matrix4f.h b/source/Matrix4f.h new file mode 100644 index 0000000..85946c0 --- /dev/null +++ b/source/Matrix4f.h @@ -0,0 +1,15 @@ +#include<math.h>
 +class Matrix4f
 +{
 +public:
 +	float m[4][4];
 +	Matrix4f();
 +	Matrix4f multiply(Matrix4f& a);
 +	Matrix4f operator* (Matrix4f& a);
 +	static Matrix4f identity();
 +	static Matrix4f move(float kx, float ky, float kz);
 +	static Matrix4f rotate(float xs, float ys, float zs);
 +	static Matrix4f scale(float px, float py, float pz);
 +	static Matrix4f perspective(float near, float far, float fov, float aspectRatio);
 +};
 +
 diff --git a/source/ObjModel.cpp b/source/ObjModel.cpp new file mode 100644 index 0000000..f23cfc3 --- /dev/null +++ b/source/ObjModel.cpp @@ -0,0 +1,93 @@ +#include "ObjModel.h"
 +
 +
 +
 +ObjModel::ObjModel() {}
 +
 +ObjModel::ObjModel(std::string fileName)
 +{
 +	int hlp = 0;
 +	std::ifstream f(fileName);
 +	std::string s0;
 +	while (getline(f, s0)) {
 +		std::stringstream ss0(s0);
 +		std::string s1 = "";
 +		ss0 >> s1;
 +		if (s1.compare(0, s1.length(), "v") == 0) {
 +			ss0 >> s1;
 +			float x = std::stof(s1);
 +			ss0 >> s1;
 +			float y = std::stof(s1);
 +			ss0 >> s1;
 +			float z = std::stof(s1);
 +			Vertice t(x, y, z, 1.0f, 0.0f, 0.0f);
 +			vertices.push_back(t);
 +		}
 +		else if (s1.compare(0, s1.length(), "vn") == 0) {
 +			ss0 >> s1;
 +			float x = std::stof(s1);
 +			ss0 >> s1;
 +			float y = std::stof(s1);
 +			ss0 >> s1;
 +			float z = std::stof(s1);
 +			Vector4f v(x, y, z, 0.0f);
 +			normals.push_back(v);
 +		}
 +		else if (s1.compare(0, s1.length(), "vt") == 0) {
 +			ss0 >> s1;
 +			float u = std::stof(s1);
 +			ss0 >> s1;
 +			float v = std::stof(s1);
 +			Texture_Coordinates kt;
 +			kt.u = u;	kt.v = v;
 +			uvcoo.push_back(kt);
 +		}
 +		else if (s1.compare(0, s1.length(), "f") == 0) {
 +			Triangle pt;
 +			for (int i = 0; i < 3; i++) {
 +				ss0 >> s1;
 +				std::stringstream ss1(s1);
 +				std::string s2;
 +				for (int j = 0; std::getline(ss1, s2, '/'); j++) {
 +					pt.p[i][j] = std::stoi(s2);
 +				}
 +			}
 +			faces.push_back(pt);
 +		}
 +	}
 +
 +}
 +
 +ObjModel::ObjModel(const ObjModel& a) 
 +{
 +	vertices = a.vertices;
 +	uvcoo = a.uvcoo;
 +	normals = a.normals;
 +	faces = a.faces;
 +}
 +
 +ObjModel ObjModel::multiplyMatrix(Matrix4f& a) 
 +{
 +	ObjModel hlp = *this;
 +	for (int i = 0; i < vertices.size(); i++)
 +	{
 +		hlp.vertices[i] = hlp.vertices[i].multiplyMatrix(a);
 +	}
 +	return hlp;
 +}
 +
 +void ObjModel::divideW() 
 +{
 +	for (int i = 0; i < vertices.size(); i++)
 +	{
 +		vertices[i] = vertices[i].divideW();
 +	}
 +}
 +
 +void ObjModel::screenspace(int width, int height)
 +{
 +	for (int i = 0; i < vertices.size(); i++)
 +	{
 +		vertices[i].screenspace(width, height);
 +	}
 +}
 diff --git a/source/ObjModel.h b/source/ObjModel.h new file mode 100644 index 0000000..9f66867 --- /dev/null +++ b/source/ObjModel.h @@ -0,0 +1,31 @@ +#include"Vertice.h"
 +#include"Bitmap.h"
 +#include<vector>
 +#include<string>
 +#include<sstream>
 +#include<fstream>
 +#include<exception>
 +
 +struct Triangle {
 +	int p[3][3];
 +};
 +
 +struct Texture_Coordinates {
 +	float u, v;
 +};
 +
 +class ObjModel
 +{
 +public:
 +	std::vector<Vertice> vertices;
 +	std::vector<Texture_Coordinates> uvcoo;
 +	std::vector<Vector4f> normals;
 +	std::vector<Triangle> faces;
 +	ObjModel();
 +	ObjModel(std::string fileName);
 +	ObjModel(const ObjModel& a);
 +	ObjModel multiplyMatrix(Matrix4f& a);
 +	void divideW();
 +	void screenspace(int width, int height);
 +};
 +
 diff --git a/source/Render.cpp b/source/Render.cpp new file mode 100644 index 0000000..7aabc43 --- /dev/null +++ b/source/Render.cpp @@ -0,0 +1,98 @@ +#include <limits>
 +
 +#include "Render.h"
 +
 +Render::Render(int width_, int height_) : Bitmap(width_, height_)
 +{
 +	zBuffer = new float[width * height];
 +	for (int i = 0; i < width * height; i++)
 +		zBuffer[i] = std::numeric_limits<float>::infinity();
 +}
 +
 +float Render::edgeFun(const Vertice& A, const Vertice& B, const Vertice& P)
 +{
 +	return ((P.x - A.x)*(B.y - A.y) - (P.y - A.y)*(B.x - A.x));
 +}
 +
 +void Render::drawTriangle(Vertice t1, Vertice t2, Vertice t3, Bitmap& texture)
 +{
 +	int maxx = fmax(t1.x, fmax(t2.x, t3.x));
 +	int minx = fmin(t1.x, fmin(t2.x, t3.x));
 +	int maxy = fmax(t1.y, fmax(t2.y, t3.y));
 +	int miny = fmin(t1.y, fmin(t2.y, t3.y));
 +
 +	Vertice p((float)minx + 0.5f, (float)miny + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f);
 +	
 +	int surface = edgeFun(t1, t2, t3);
 +	int w1_row = edgeFun(t2, t3, p);	int w1xk = (t3.y - t2.y), w1yk = -(t3.x - t2.x);
 +	int w2_row = edgeFun(t3, t1, p);	int w2xk = (t1.y - t3.y), w2yk = -(t1.x - t3.x);
 +	int w3_row = edgeFun(t1, t2, p);	int w3xk = (t2.y - t1.y), w3yk = -(t2.x - t1.x);
 +
 +	for (int y = miny; y < maxy; y++) {
 +		int w1_vertice = w1_row;
 +		int w2_vertice = w2_row;
 +		int w3_vertice = w3_row;
 +		for (int x = minx; x < maxx; x++) {
 +
 +			float w1 = w1_vertice;
 +			float w2 = w2_vertice;
 +			float w3 = w3_vertice;
 +			
 +				if ((w3 >= 0 && w1 >= 0 && w2 >= 0) || (w3 <= 0 && w1 <= 0 && w2 <= 0))
 +				{
 +					w1 /= surface;
 +					w2 /= surface;
 +					w3 /= surface;
 +
 +					float w = 1.0f / (w1 * t1.w + w2 * t2.w + w3 * t3.w);
 +					float z =/* w * */1.0f / ((w1 * t1.z + w2 * t2.z + w3 * t3.z) * w);
 +					if (zBuffer[(y * (width)) + x] > z) {
 +						zBuffer[(y * (width)) + x] = z;
 +						float u = w * (w1 * t1.u + w2 * t2.u + w3 * t3.u);
 +						float v = w * (w1 * t1.v + w2 * t2.v + w3 * t3.v);
 +
 +						u = round((u * texture.width));
 +						v = round((v * (texture.height - 1)));
 +
 +						int hlp = ((v * texture.width) + u) * 4;
 +						int r = texture.pixels[hlp + 0];
 +						int g = texture.pixels[hlp + 1];
 +						int b = texture.pixels[hlp + 2];
 +						setPixel(x, y, r, g, b);
 +					}
 +				}
 +			
 +			w1_vertice += w1xk;
 +			w2_vertice += w2xk;
 +			w3_vertice += w3xk;
 +		}
 +		
 +		w1_row += w1yk;
 +		w2_row += w2yk;
 +		w3_row += w3yk;
 +	}
 +}
 +
 +
 +void Render::renderModel(ObjModel& model, Bitmap& texture)
 +{
 +	for (int i = 0; i < model.faces.size(); i++) {
 +		
 +		model.vertices[model.faces[i].p[0][0] - 1].u = model.uvcoo[model.faces[i].p[0][1] - 1].u * model.vertices[model.faces[i].p[0][0] - 1].w;
 +		model.vertices[model.faces[i].p[0][0] - 1].v = model.uvcoo[model.faces[i].p[0][1] - 1].v * model.vertices[model.faces[i].p[0][0] - 1].w;
 +
 +		model.vertices[model.faces[i].p[1][0] - 1].u = model.uvcoo[model.faces[i].p[1][1] - 1].u * model.vertices[model.faces[i].p[1][0] - 1].w;
 +		model.vertices[model.faces[i].p[1][0] - 1].v = model.uvcoo[model.faces[i].p[1][1] - 1].v * model.vertices[model.faces[i].p[1][0] - 1].w;
 +
 +		model.vertices[model.faces[i].p[2][0] - 1].u = model.uvcoo[model.faces[i].p[2][1] - 1].u * model.vertices[model.faces[i].p[2][0] - 1].w;
 +		model.vertices[model.faces[i].p[2][0] - 1].v = model.uvcoo[model.faces[i].p[2][1] - 1].v * model.vertices[model.faces[i].p[2][0] - 1].w;
 +		
 +
 +		drawTriangle(model.vertices[model.faces[i].p[0][0] - 1], model.vertices[model.faces[i].p[1][0] - 1], model.vertices[model.faces[i].p[2][0] - 1], texture);
 +	}
 +}
 +
 +void Render::resetZBuf() {
 +	for (int i = 0; i < width * height; i++)
 +		zBuffer[i] = std::numeric_limits<float>::infinity();
 +}
 diff --git a/source/Render.h b/source/Render.h new file mode 100644 index 0000000..386cbcb --- /dev/null +++ b/source/Render.h @@ -0,0 +1,13 @@ +#include"ObjModel.h"
 +class Render : public Bitmap
 +{
 +private:
 +	float edgeFun(const Vertice& A, const Vertice& B, const Vertice& P);
 +public:
 +	float* zBuffer;
 +	Render(int width_, int height_);
 +	void drawTriangle(Vertice t1, Vertice t2, Vertice t3, Bitmap& texture);
 +	void renderModel(ObjModel& model, Bitmap& texture);
 +	void resetZBuf();
 +};
 +
 diff --git a/source/Vector4f.cpp b/source/Vector4f.cpp new file mode 100644 index 0000000..506dc22 --- /dev/null +++ b/source/Vector4f.cpp @@ -0,0 +1,32 @@ +#include "Vector4f.h"
 +
 +Vector4f::Vector4f() {}
 +
 +Vector4f::Vector4f(float x_, float y_, float z_, float w_) 
 +{
 +	x = x_;
 +	y = y_;
 +	z = z_;
 +	w = w_;
 +}
 +
 +float Vector4f::dotProduct(const Vector4f& a)
 +{
 +	return ((x * a.x) + (y * a.y) + (z * a.z));
 +}
 +
 +Vector4f Vector4f::crossProduct(const Vector4f& a)
 +{
 +	return Vector4f((y * a.z - z * a.y), (z * a.x - x * a.z), (x * a.y - y * a.x), (w * a.w));
 +}
 +
 +Vector4f Vector4f::multiplyMatrix(const Matrix4f& a)
 +{
 +	float x1, y1, z1, w1;
 +	x1 = ((x * a.m[0][0]) + (y * a.m[0][1]) + (z * a.m[0][2]) + (w * a.m[0][3]));
 +	y1 = ((x * a.m[1][0]) + (y * a.m[1][1]) + (z * a.m[1][2]) + (w * a.m[1][3]));
 +	z1 = ((x * a.m[2][0]) + (y * a.m[2][1]) + (z * a.m[2][2]) + (w * a.m[2][3]));
 +	w1 = ((x * a.m[3][0]) + (y * a.m[3][1]) + (z * a.m[3][2]) + (w * a.m[3][3]));
 +	return Vector4f(x1, y1, z1, w1);
 +}
 +
 diff --git a/source/Vector4f.h b/source/Vector4f.h new file mode 100644 index 0000000..ee1846a --- /dev/null +++ b/source/Vector4f.h @@ -0,0 +1,12 @@ +#include"Matrix4f.h"
 +class Vector4f
 +{
 +public:
 +	float x, y, z, w;
 +	Vector4f();
 +	Vector4f(float x_, float y_, float z_, float w_);
 +	float dotProduct(const Vector4f& a);
 +	Vector4f crossProduct(const Vector4f& a);
 +	Vector4f multiplyMatrix(const Matrix4f& a);
 +};
 +
 diff --git a/source/Vertice.cpp b/source/Vertice.cpp new file mode 100644 index 0000000..022c477 --- /dev/null +++ b/source/Vertice.cpp @@ -0,0 +1,46 @@ +#include "Vertice.h"
 +
 +Vertice::Vertice() : Vector4f() {}
 +
 +Vertice::Vertice(float x_, float y_, float z_, float u_, float v_) : Vector4f (x_, y_, z_, 1)
 +{
 +	u = u_;
 +	v = v_;
 +}
 +
 +Vertice::Vertice(float x_, float y_, float z_, float w_, float u_, float v_) : Vector4f(x_, y_, z_, w_)
 +{
 +	u = u_;
 +	v = v_;
 +}
 +
 +void Vertice::screenspace(int screenWidth, int screenHeight)
 +{
 +	x = round(((x + 1.0f) / 2.0f) * screenWidth);
 +	y = round(((-y + 1.0f) / 2.0f) * screenHeight);
 +}
 +
 +Vertice Vertice::multiplyMatrix(const Matrix4f& a)
 +{
 +	float x1, y1, z1, w1;
 +	x1 = ((x * a.m[0][0]) + (y * a.m[0][1]) + (z * a.m[0][2]) + (w * a.m[0][3]));
 +	y1 = ((x * a.m[1][0]) + (y * a.m[1][1]) + (z * a.m[1][2]) + (w * a.m[1][3]));
 +	z1 = ((x * a.m[2][0]) + (y * a.m[2][1]) + (z * a.m[2][2]) + (w * a.m[2][3]));
 +	w1 = ((x * a.m[3][0]) + (y * a.m[3][1]) + (z * a.m[3][2]) + (w * a.m[3][3]));
 +	return Vertice(x1, y1, z1, w1, u, v);
 +}
 +
 +Vertice& Vertice::operator=(const Vector4f& a) 
 +{
 +	x = a.x;
 +	y = a.y;
 +	z = a.z;
 +	w = a.w;
 +	return *this;
 +}
 +
 +Vertice Vertice::divideW() 
 +{
 +	float rw = 1.0f / w;
 +	return Vertice(x * rw, y * rw, (z * rw), rw, u * rw, v * rw);
 +}
 diff --git a/source/Vertice.h b/source/Vertice.h new file mode 100644 index 0000000..c4a591b --- /dev/null +++ b/source/Vertice.h @@ -0,0 +1,14 @@ +#include"Vector4f.h"
 +class Vertice : public Vector4f
 +{
 +public:
 +	float u, v;
 +	Vertice();
 +	Vertice(float x_, float y_, float z_, float u_, float v_);
 +	Vertice(float x_, float y_, float z_, float w_, float u_, float v_);
 +	void screenspace(int screenWidth, int screenHeight);
 +	Vertice multiplyMatrix(const Matrix4f& a);
 +	Vertice& operator= (const Vector4f& a);
 +	Vertice divideW();
 +};
 +
 diff --git a/source/main.cpp b/source/main.cpp new file mode 100644 index 0000000..977d8ae --- /dev/null +++ b/source/main.cpp @@ -0,0 +1,83 @@ +#include<chrono>
 +
 +#include<SFML/Window.hpp>
 +#include<SFML/Graphics.hpp>
 +
 +#include"Render.h"
 +
 +int main()
 +{
 +	float width, height;
 +	float fov;
 +	std::cout << "Enter window width and height.\n";
 +	std::cin >> width >> height;
 +	std::cout << "Enter Field of View.\n";
 +	std::cin >> fov;
 +	std::cout << "Loading...\n";
 +
 +	sf::RenderWindow window(sf::VideoMode(width, height), "C++ CPU Renderer", sf::Style::Titlebar | sf::Style::Close);
 +	sf::Event event;
 +
 +	window.setFramerateLimit(60);
 +
 +	sf::Texture texture;
 +	texture.create(width, height);
 +
 +	sf::Sprite sprite(texture);
 +
 +	sf::Clock clock;
 +	sf::Time time;
 +
 +	Render render(width, height);	
 +
 +	sf::Image image;
 +	image.loadFromFile("rusImage.png");
 +	Bitmap map(image.getSize().x, image.getSize().y);
 +	const sf::Uint8* pp = image.getPixelsPtr();
 +	for (int i = 0; i < image.getSize().x * image.getSize().y * 4; i += 4) {
 +		map.pixels[i + 0] = (unsigned char)pp[i + 0];
 +		map.pixels[i + 1] = (unsigned char)pp[i + 1];
 +		map.pixels[i + 2] = (unsigned char)pp[i + 2];
 +		map.pixels[i + 3] = (unsigned char)pp[i + 3];
 +	}
 +
 +	std::chrono::high_resolution_clock::time_point time1 = std::chrono::high_resolution_clock::now();
 +	ObjModel vehicle("rus3.obj");
 +	std::chrono::high_resolution_clock::time_point time2 = std::chrono::high_resolution_clock::now();
 +	std::chrono::duration<double> speed = std::chrono::duration_cast<std::chrono::duration<double>>(time2 - time1);
 +	std::cout << "Model loading time: " << speed.count() << "s\n";
 +	std::cout << "Vertice count: " << vehicle.vertices.size() << "\nNumber of normals: " << vehicle.normals.size() << "\nUV count: " << vehicle.uvcoo.size() << "\n";
 +	std::cout << "Number of faces: " << vehicle.faces.size() << "\n";
 +
 +	while (window.isOpen())
 +	{
 +		while (window.pollEvent(event))
 +			if (event.type == sf::Event::Closed)
 +				window.close();
 +
 +		time = clock.getElapsedTime();
 +
 +		Vertice a1, b1, c1, d1, e1, f1;
 +
 +		Matrix4f move = Matrix4f::move(0.0f, -150.0f, 600.0f);
 +		Matrix4f rotate = Matrix4f::rotate(0.0f, time.asSeconds() * 25.0f, 0.0f);
 +		Matrix4f scale = Matrix4f::scale(1.0f, 1.0f, 1.0f);
 +		Matrix4f project = Matrix4f::perspective(1.0f, 10000.0f, fov, width / height);
 +		Matrix4f end_matrix = project * move * rotate * scale;
 +	
 +		ObjModel vehicle2 = vehicle.multiplyMatrix(end_matrix);
 +		vehicle2.divideW();
 +		vehicle2.screenspace(width, height);
 +		
 +
 +		render.fill(255, 255, 255);
 +		render.resetZBuf();
 +		render.renderModel(vehicle2, map);
 +		
 +		texture.update((sf::Uint8*)render.pixels);
 +		window.draw(sprite);
 +		window.display();
 +	}
 +
 +	return 0;
 +}
 | 
