-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGeometry.cpp
133 lines (117 loc) · 4.49 KB
/
Geometry.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
/*********************************************************************
* This file provide implementations for the functions declared
* in Geometry.h
* It serves as an alternative to the now deprecated fixed-function
* pipeline that GLUT utilizes. DO NOT MODIFY WHEN DOING THIS HOMEWORK!
* Author: Hoang Tran
* Written in July 2016.
*********************************************************************/
#include "Geometry.h"
// Avoiding linker error caused by multiply defined variables
GLuint defaultVAO, defaultVBO, defaultNBO, defaultEBO;
GLuint vertexshader, fragmentshader, shaderprogram;
GLuint modelviewPos;
glm::mat4 model;
shape lastUsed = NONE;
/** TEAPOT RELATED **/
std::vector <glm::vec3> teapotVertices;
std::vector <glm::vec3> teapotNormals;
std::vector <unsigned int> teapotIndices;
// Initialize the buffer objects. Can only be called after OpenGL is initialized.
void initBufferObjects() {
// Tell OpenGL to allocate us some space for the VAO
glGenVertexArrays(1, &defaultVAO);
// Now allocate some space for all the buffer objects
glGenBuffers(1, &defaultVBO);
glGenBuffers(1, &defaultNBO);
glGenBuffers(1, &defaultEBO);
}
// Free up any dynamically allocated memory here
void destroyBufferObjects() {
// Delete every vertex array and buffer generated by OpenGL
glDeleteVertexArrays(1, &defaultVAO);
glDeleteBuffers(1, &defaultVBO);
glDeleteBuffers(1, &defaultNBO);
glDeleteBuffers(1, &defaultEBO);
}
// OBJ file parser function. Used for loading the teapot.obj file.
void parse(const char * filepath) {
FILE* fp;
float x, y, z;
int fx, fy, fz, ignore;
int c1, c2;
float minY = INFINITY, minZ = INFINITY;
float maxY = -INFINITY, maxZ = -INFINITY;
fp = fopen(filepath, "rb");
if (fp == NULL) {
std::cerr << "Error loading file: " << filepath << std::endl;
std::getchar();
exit(-1);
}
while (!feof(fp)) {
c1 = fgetc(fp);
while (!(c1 == 'v' || c1 == 'f')) {
c1 = fgetc(fp);
if (feof(fp))
break;
}
c2 = fgetc(fp);
if ((c1 == 'v') && (c2 == ' ')) {
fscanf(fp, "%f %f %f", &x, &y, &z);
teapotVertices.push_back(glm::vec3(x, y, z));
if (y < minY) minY = y;
if (z < minZ) minZ = z;
if (y > maxY) maxY = y;
if (z > maxZ) maxZ = z;
}
else if ((c1 == 'v') && (c2 == 'n')) {
fscanf(fp, "%f %f %f", &x, &y, &z);
teapotNormals.push_back(glm::normalize(glm::vec3(x, y, z)));
}
else if (c1 == 'f')
{
fscanf(fp, "%d//%d %d//%d %d//%d", &fx, &ignore, &fy, &ignore, &fz, &ignore);
teapotIndices.push_back(fx - 1);
teapotIndices.push_back(fy - 1);
teapotIndices.push_back(fz - 1);
}
}
fclose(fp); // Finished parsing
// Recenter the teapot
float avgY = (minY + maxY) / 2.0f - 0.0234f;
float avgZ = (minZ + maxZ) / 2.0f;
for (unsigned int i = 0; i < teapotVertices.size(); ++i) {
glm::vec3 shiftedVertex = (teapotVertices[i] - glm::vec3(0.0f, avgY, avgZ)) * glm::vec3(0.975f, 0.975f, 0.975f);
teapotVertices[i] = shiftedVertex;
}
}
// Bind the teapot data to a VAO.
void bindTeapot() {
glBindVertexArray(defaultVAO);
// Use layout location 0 for the vertex positions
glBindBuffer(GL_ARRAY_BUFFER, defaultVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * teapotVertices.size(), &teapotVertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0); // This allows usage of layout location 0 in the vertex shader
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
// Use layout location 1 for the normals
glBindBuffer(GL_ARRAY_BUFFER, defaultNBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * teapotNormals.size(), &teapotNormals[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1); // This allows usage of layout location 1 in the vertex shader
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, defaultEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * teapotIndices.size(), &teapotIndices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
lastUsed = TEAPOT;
}
// Draws a teapot
void solidTeapot(float size) {
model = glm::scale(glm::mat4(1.0f), glm::vec3(size, size, size));
glUniformMatrix4fv(modelviewPos, 1, GL_FALSE, &(view * model)[0][0]);
if (lastUsed != TEAPOT) {
bindTeapot();
}
glBindVertexArray(defaultVAO);
glDrawElements(GL_TRIANGLES, teapotIndices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0); // Unbind the VAO when done
}