-
Notifications
You must be signed in to change notification settings - Fork 0
/
glorthoprojmatrix.cpp
146 lines (112 loc) · 3.35 KB
/
glorthoprojmatrix.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* Follow code in Projective projection matrix. */
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <fstream>
#include <cmath>
#include <iomanip>
#include <limits>
#include "stdint.h"
#include "string.h"
#include "geometry.h"
#include "vertexdata.h"
#ifndef M_PI
#define M_PI 3.14159265
#endif
void glOrtho(
Mat44f &M,
float &b,
float &t,
float &l,
float &r,
float &near,
float &far
)
{
M[0][0] = 2 / (r - l);
M[0][1] = M[0][1] = M[0][3] = 0;
M[1][1] = 2 / (t - b);
M[1][0] = M[1][2] = M[1][3] = 0;
M[3][0] = -(r + l) / (r - l);
M[3][1] = -(t + b) / (t - b);
M[3][2] = - (far + near) / (far - near);
M[3][3] = 1;
M[2][0] = 0;
M[2][1] = 0;
M[2][2] = - 2 / (far -near);
M[2][3] = 0;
}
void gluPerspective(
float &angleOfView,
float imageAspectRatio,
float &near, float &far,
float &b, float &t, float &l, float &r
)
{
t = near * tan(angleOfView * 0.5 * M_PI / 180);
r = imageAspectRatio * t;
l = -r;
b = -t;
}
int main()
{
Mat44f Mproj;
Mat44f worldToCamera = {0.95424, 0.20371, -0.218924, 0, 0, 0.732087, 0.681211, 0, 0.299041, -0.650039, 0.698587, 0, -0.553677, -3.920548, -62.68137, 1};
float angleOfView = 90;
float near = 0.1;
float far = 100;
float b, t, l, r=0;
uint32_t imageWidth = 512;
uint32_t imageHeight = 512;
const float kInfinity = std::numeric_limits<float>::max();
Vec3f minWorld(kInfinity), maxWorld(-kInfinity);
for (int i = 0; i < numVertices; i++)
{
minWorld.x = std::min(vertices[i].x, minWorld.x);
minWorld.y = std::min(vertices[i].y, minWorld.y);
minWorld.z = std::min(vertices[i].z, minWorld.z);
maxWorld.x = std::max(vertices[i].x, maxWorld.x);
maxWorld.y = std::max(vertices[i].y, maxWorld.y);
maxWorld.z = std::max(vertices[i].z, maxWorld.z);
}
Vec3f minCamera, maxCamera;
worldToCamera.multiple(minWorld, minCamera);
worldToCamera.multiple(maxWorld, maxCamera);
float maxx = std::max(fabs(minCamera.x), fabs(maxCamera.x));
float maxy = std::max(fabs(minCamera.y), fabs(maxCamera.y));
float max = std::max(maxx, maxy);
r = t = max; //512 x 512
l = -r; b = -t;
glOrtho(Mproj, b, t, l, r, near, far);
uint8_t *buffer = new uint8_t[imageWidth * imageHeight];
memset(buffer, 0, imageWidth * imageHeight);
std::cerr << Mproj << std::endl;
std::cerr << worldToCamera << std::endl;
for (int i = 0; i < numVertices; i++)
{
Vec3f world = vertices[i];
Vec3f camera;
Vec3f proj;
worldToCamera.multiple(world, camera);
Mproj.multiple(camera, proj);
if (proj.x < -1 || proj.x > 1 || proj.y < -1 || proj.y > 1)
{
continue;
}
Vec2f ndc;
/* [0, 1] */
ndc.x = (proj.x + 1) / 2;
ndc.y = 1 - (proj.y + 1) / 2;
uint32_t x = std::min(imageWidth - 1, (uint32_t)(ndc.x * imageWidth));
uint32_t y = std::min(imageHeight - 1, (uint32_t)(ndc.y * imageHeight));
buffer[y * imageWidth + x] = 255;
}
// save to file
std::ofstream ofs;
ofs.open("./glorthoprojmatrix.ppm");
ofs << "P5\n" << imageWidth << " " << imageHeight << "\n255\n";
ofs.write((char*)buffer, imageWidth * imageHeight);
ofs.close();
delete [] buffer;
return 0;
}