-
Notifications
You must be signed in to change notification settings - Fork 0
/
glprojmatrix.cpp
123 lines (95 loc) · 2.52 KB
/
glprojmatrix.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
/* Follow code in Projective projection matrix. */
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <fstream>
#include <cmath>
#include <iomanip>
#include "stdint.h"
#include "string.h"
#include "geometry.h"
#include "vertexdata.h"
#ifndef M_PI
#define M_PI 3.14159265
#endif
void glFrustum(
Mat44f &M,
float &b,
float &t,
float &l,
float &r,
float &near,
float &far
)
{
M[0][0] = 2 * near / (r - l);
M[0][1] = M[0][1] = M[0][3] = 0;
M[1][1] = 2 * near / (t - b);
M[1][0] = M[1][2] = M[1][3] = 0;
M[2][0] = (r + l) / (r - l);
M[2][1] = (t + b) / (t - b);
M[2][2] = - (far + near) / (far - near);
M[2][3] = -1;
M[3][0] = 0;
M[3][1] = 0;
M[3][2] = - 2 * far * near / (far -near);
M[3][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 worldToCamera;
Mat44f Mproj;
worldToCamera[3][1] = -10;
worldToCamera[3][2] = -20;
float angleOfView = 90;
float near = 0.1;
float far = 100;
float b, t, l, r=0;
uint32_t imageWidth = 512;
uint32_t imageHeight = 512;
gluPerspective(angleOfView, imageWidth / (float)imageHeight, near, far, b, t, l, r);
glFrustum(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("./projmatrix.ppm");
ofs << "P5\n" << imageWidth << " " << imageHeight << "\n255\n";
ofs.write((char*)buffer, imageWidth * imageHeight);
ofs.close();
delete [] buffer;
return 0;
}