Skip to content

Commit f6fecb7

Browse files
committed
wireframe rendering
1 parent 28b766a commit f6fecb7

File tree

5 files changed

+6517
-18
lines changed

5 files changed

+6517
-18
lines changed

geometry.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#ifndef __GEOMETRY_H__
2+
#define __GEOMETRY_H__
3+
4+
#include <cmath>
5+
6+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7+
8+
template <class t> struct Vec2 {
9+
union {
10+
struct {t u, v;};
11+
struct {t x, y;};
12+
t raw[2];
13+
};
14+
Vec2() : u(0), v(0) {}
15+
Vec2(t _u, t _v) : u(_u),v(_v) {}
16+
inline Vec2<t> operator +(const Vec2<t> &V) const { return Vec2<t>(u+V.u, v+V.v); }
17+
inline Vec2<t> operator -(const Vec2<t> &V) const { return Vec2<t>(u-V.u, v-V.v); }
18+
inline Vec2<t> operator *(float f) const { return Vec2<t>(u*f, v*f); }
19+
template <class > friend std::ostream& operator<<(std::ostream& s, Vec2<t>& v);
20+
};
21+
22+
template <class t> struct Vec3 {
23+
union {
24+
struct {t x, y, z;};
25+
struct { t ivert, iuv, inorm; };
26+
t raw[3];
27+
};
28+
Vec3() : x(0), y(0), z(0) {}
29+
Vec3(t _x, t _y, t _z) : x(_x),y(_y),z(_z) {}
30+
inline Vec3<t> operator ^(const Vec3<t> &v) const { return Vec3<t>(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); }
31+
inline Vec3<t> operator +(const Vec3<t> &v) const { return Vec3<t>(x+v.x, y+v.y, z+v.z); }
32+
inline Vec3<t> operator -(const Vec3<t> &v) const { return Vec3<t>(x-v.x, y-v.y, z-v.z); }
33+
inline Vec3<t> operator *(float f) const { return Vec3<t>(x*f, y*f, z*f); }
34+
inline t operator *(const Vec3<t> &v) const { return x*v.x + y*v.y + z*v.z; }
35+
float norm () const { return std::sqrt(x*x+y*y+z*z); }
36+
Vec3<t> & normalize(t l=1) { *this = (*this)*(l/norm()); return *this; }
37+
template <class > friend std::ostream& operator<<(std::ostream& s, Vec3<t>& v);
38+
};
39+
40+
typedef Vec2<float> Vec2f;
41+
typedef Vec2<int> Vec2i;
42+
typedef Vec3<float> Vec3f;
43+
typedef Vec3<int> Vec3i;
44+
45+
template <class t> std::ostream& operator<<(std::ostream& s, Vec2<t>& v) {
46+
s << "(" << v.x << ", " << v.y << ")\n";
47+
return s;
48+
}
49+
50+
template <class t> std::ostream& operator<<(std::ostream& s, Vec3<t>& v) {
51+
s << "(" << v.x << ", " << v.y << ", " << v.z << ")\n";
52+
return s;
53+
}
54+
55+
#endif //__GEOMETRY_H__

main.cpp

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
#include <vector>
12
#include <cmath>
23
#include "tgaimage.h"
4+
#include "model.h"
5+
#include "geometry.h"
36

47
const TGAColor white = TGAColor(255, 255, 255, 255);
58
const TGAColor red = TGAColor(255, 0, 0, 255);
9+
Model *model = NULL;
10+
const int width = 800;
11+
const int height = 800;
612

713
void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
814
bool steep = false;
@@ -15,35 +21,42 @@ void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
1521
std::swap(x0, x1);
1622
std::swap(y0, y1);
1723
}
18-
int dx = x1-x0;
19-
int dy = y1-y0;
20-
int derror2 = std::abs(dy)*2;
21-
int error2 = 0;
22-
int y = y0;
24+
2325
for (int x=x0; x<=x1; x++) {
26+
float t = (x-x0)/(float)(x1-x0);
27+
int y = y0*(1.-t) + y1*t;
2428
if (steep) {
25-
image.set(y, x, TGAColor(255, 1));
29+
image.set(y, x, color);
2630
} else {
27-
image.set(x, y, TGAColor(255, 1));
28-
}
29-
error2 += derror2;
30-
31-
if (error2>dx) {
32-
y += (y1>y0?1:-1);
33-
error2 -= dx*2;
31+
image.set(x, y, color);
3432
}
3533
}
3634
}
3735

3836
int main(int argc, char** argv) {
39-
TGAImage image(100, 100, TGAImage::RGB);
40-
for (int i=0; i<1000000; i++) {
41-
line(13, 20, 80, 40, image, white);
42-
line(20, 13, 40, 80, image, red);
43-
line(80, 40, 13, 20, image, red);
37+
if (2==argc) {
38+
model = new Model(argv[1]);
39+
} else {
40+
model = new Model("obj/african_head.obj");
4441
}
42+
43+
TGAImage image(width, height, TGAImage::RGB);
44+
for (int i=0; i<model->nfaces(); i++) {
45+
std::vector<int> face = model->face(i);
46+
for (int j=0; j<3; j++) {
47+
Vec3f v0 = model->vert(face[j]);
48+
Vec3f v1 = model->vert(face[(j+1)%3]);
49+
int x0 = (v0.x+1.)*width/2.;
50+
int y0 = (v0.y+1.)*height/2.;
51+
int x1 = (v1.x+1.)*width/2.;
52+
int y1 = (v1.y+1.)*height/2.;
53+
line(x0, y0, x1, y1, image, white);
54+
}
55+
}
56+
4557
image.flip_vertically(); // i want to have the origin at the left bottom corner of the image
4658
image.write_tga_file("output.tga");
59+
delete model;
4760
return 0;
4861
}
4962

model.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include <iostream>
2+
#include <string>
3+
#include <fstream>
4+
#include <sstream>
5+
#include <vector>
6+
#include "model.h"
7+
8+
Model::Model(const char *filename) : verts_(), faces_() {
9+
std::ifstream in;
10+
in.open (filename, std::ifstream::in);
11+
if (in.fail()) return;
12+
std::string line;
13+
while (!in.eof()) {
14+
std::getline(in, line);
15+
std::istringstream iss(line.c_str());
16+
char trash;
17+
if (!line.compare(0, 2, "v ")) {
18+
iss >> trash;
19+
Vec3f v;
20+
for (int i=0;i<3;i++) iss >> v.raw[i];
21+
verts_.push_back(v);
22+
} else if (!line.compare(0, 2, "f ")) {
23+
std::vector<int> f;
24+
int itrash, idx;
25+
iss >> trash;
26+
while (iss >> idx >> trash >> itrash >> trash >> itrash) {
27+
idx--; // in wavefront obj all indices start at 1, not zero
28+
f.push_back(idx);
29+
}
30+
faces_.push_back(f);
31+
}
32+
}
33+
std::cerr << "# v# " << verts_.size() << " f# " << faces_.size() << std::endl;
34+
}
35+
36+
Model::~Model() {
37+
}
38+
39+
int Model::nverts() {
40+
return (int)verts_.size();
41+
}
42+
43+
int Model::nfaces() {
44+
return (int)faces_.size();
45+
}
46+
47+
std::vector<int> Model::face(int idx) {
48+
return faces_[idx];
49+
}
50+
51+
Vec3f Model::vert(int i) {
52+
return verts_[i];
53+
}
54+

model.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef __MODEL_H__
2+
#define __MODEL_H__
3+
4+
#include <vector>
5+
#include "geometry.h"
6+
7+
class Model {
8+
private:
9+
std::vector<Vec3f> verts_;
10+
std::vector<std::vector<int> > faces_;
11+
public:
12+
Model(const char *filename);
13+
~Model();
14+
int nverts();
15+
int nfaces();
16+
Vec3f vert(int i);
17+
std::vector<int> face(int idx);
18+
};
19+
20+
#endif //__MODEL_H__

0 commit comments

Comments
 (0)