diff --git a/BaseGLProject/ADrawable.h b/BaseGLProject/ADrawable.h
index a2038d6..5680d7e 100644
--- a/BaseGLProject/ADrawable.h
+++ b/BaseGLProject/ADrawable.h
@@ -36,7 +36,7 @@ protected:
public:
- virtual void draw(ShaderProgram *shader, glm::mat4x4 pv) = 0;
+ virtual void draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) = 0;
virtual DrawableType getType() = 0;
void addRotation(glm::vec4 vec) override
diff --git a/BaseGLProject/BaseGLProject.vcxproj b/BaseGLProject/BaseGLProject.vcxproj
index a5dbd77..4e88a62 100644
--- a/BaseGLProject/BaseGLProject.vcxproj
+++ b/BaseGLProject/BaseGLProject.vcxproj
@@ -157,6 +157,8 @@
+
+
@@ -177,11 +179,14 @@
+
+
+
-
+
Geometry
4.0
Geometry
@@ -192,6 +197,7 @@
4.0
Document
+
diff --git a/BaseGLProject/BaseGLProject.vcxproj.filters b/BaseGLProject/BaseGLProject.vcxproj.filters
index cefa8ea..c1fdb2a 100644
--- a/BaseGLProject/BaseGLProject.vcxproj.filters
+++ b/BaseGLProject/BaseGLProject.vcxproj.filters
@@ -60,6 +60,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
@@ -116,11 +122,23 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
Shaders
+
+ Shaders
+
Shaders
diff --git a/BaseGLProject/CheckeredFloor.cpp b/BaseGLProject/CheckeredFloor.cpp
index 2a06fdf..98d2bd9 100644
--- a/BaseGLProject/CheckeredFloor.cpp
+++ b/BaseGLProject/CheckeredFloor.cpp
@@ -80,12 +80,12 @@ CheckeredFloor::~CheckeredFloor()
{
}
-void CheckeredFloor::draw(ShaderProgram * shader, glm::mat4x4 pv)
+void CheckeredFloor::draw(ShaderProgram * shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix)
{
_model.glPushMatrix();
effectTransformations();
glBindVertexArray(_vaoHandle);
- glm::mat4 mvpMatrix = pv * _model.getMatrix();
+ glm::mat4 mvpMatrix = proj_matrix * view_matrix * _model.getMatrix();
glUniformMatrix4fv(shader->uniform("mvp"), 1, GL_FALSE, glm::value_ptr(mvpMatrix));
glDrawArrays(GL_TRIANGLES, 0, _squares * _squares * 6);
_model.glPopMatrix();
diff --git a/BaseGLProject/CheckeredFloor.h b/BaseGLProject/CheckeredFloor.h
index 4371474..7bd843b 100644
--- a/BaseGLProject/CheckeredFloor.h
+++ b/BaseGLProject/CheckeredFloor.h
@@ -25,7 +25,7 @@ private :
public :
CheckeredFloor(int size, int squares);
~CheckeredFloor();
- void draw(ShaderProgram *shader, glm::mat4x4 pv) override;
+ void draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) override;
DrawableType getType() override;
};
\ No newline at end of file
diff --git a/BaseGLProject/ColorCube.cpp b/BaseGLProject/ColorCube.cpp
index bdf6063..1e0d997 100644
--- a/BaseGLProject/ColorCube.cpp
+++ b/BaseGLProject/ColorCube.cpp
@@ -1,5 +1,13 @@
#include "ColorCube.h"
+glm::vec3 computeNormal(glm::vec3 p1, glm::vec3 p2, glm::vec3 p3)
+{
+ glm::vec3 v1 = p2 - p1;
+ glm::vec3 v2 = p3 - p1;
+
+ return glm::normalize(glm::cross(v1, v2));
+}
+
void ColorCube::iboSetup()
{
std::vector cube_vertices =
@@ -49,7 +57,6 @@ void ColorCube::iboSetup()
(void*)0);
glEnableVertexAttribArray(0); //attr number = 0
-
glGenBuffers(1, &_vbo_colors);
glBindBuffer(GL_ARRAY_BUFFER, _vbo_colors);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 24, cube_colors, GL_STATIC_DRAW);
@@ -86,14 +93,7 @@ void ColorCube::vaoSetup()
{ -1.0, 1.0, 1.0}, { 1.0, 1.0, 1.0}, { 1.0, 1.0, -1.0},
{ 1.0, 1.0, -1.0}, { -1.0, 1.0, -1.0}, { -1.0, 1.0, 1.0} };
- GLushort cube_elements[] = {
- 0, 1, 2, 2, 3, 0, 1, 5, 6,
- 6, 2, 1, 7, 6, 5, 5, 4, 7,
- 4, 0, 3, 3, 7, 4, 4, 5, 1,
- 1, 0, 4, 3, 2, 6, 6, 7, 3,
- };
-
- GLfloat cube_colors[] = {
+ std::vector cube_colors = {
1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0,
@@ -107,18 +107,17 @@ void ColorCube::vaoSetup()
1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
};
-
- GLfloat cube_colorss[] = {
- 1.0, 0.0, 0.0, // 0
- 0.0, 1.0, 0.0, // 1
- 0.0, 0.0, 1.0, // 2
- 1.0, 1.0, 1.0, // 3
- 1.0, 0.0, 0.0, // 4
- 0.0, 1.0, 0.0, // 5
- 0.0, 0.0, 1.0, // 6
- 1.0, 1.0, 1.0, // 7
- };
+ std::vector cube_normals;
+
+ for (int i = 0; i < cube_vertices.size() - 2; i += 3)
+ {
+ glm::vec3 norm = computeNormal(
+ cube_vertices[i], cube_vertices[i + 1], cube_vertices[i + 2]);
+ cube_normals.push_back(norm); cube_normals.push_back(norm); cube_normals.push_back(norm);
+ }
+
+
glGenVertexArrays(1, &_vaoHandle);
glBindVertexArray(_vaoHandle);
@@ -135,10 +134,9 @@ void ColorCube::vaoSetup()
(void*)0);
glEnableVertexAttribArray(0); //attr number = 0
-
- glGenBuffers(1, &_vbo_colors);
- glBindBuffer(GL_ARRAY_BUFFER, _vbo_colors);
- glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * cube_vertices.size() * 3, cube_colors, GL_STATIC_DRAW);
+ glGenBuffers(1, &_vbo_normals);
+ glBindBuffer(GL_ARRAY_BUFFER, _vbo_normals);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * cube_normals.size() * 3, cube_normals.data(), GL_STATIC_DRAW);
glVertexAttribPointer(
1,
@@ -149,6 +147,19 @@ void ColorCube::vaoSetup()
(void*)0);
glEnableVertexAttribArray(1);
+ glGenBuffers(1, &_vbo_colors);
+ glBindBuffer(GL_ARRAY_BUFFER, _vbo_colors);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * cube_colors.size(), cube_colors.data(), GL_STATIC_DRAW);
+
+ glVertexAttribPointer(
+ 2,
+ 3,
+ GL_FLOAT,
+ GL_FALSE,
+ 0,
+ (void*)0);
+ glEnableVertexAttribArray(2);
+
glBindVertexArray(0);
}
@@ -162,21 +173,31 @@ ColorCube::ColorCube(bool usingIBO)
}
-void ColorCube::draw(ShaderProgram *shader, glm::mat4x4 pv)
+void ColorCube::draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix)
{
_model.glPushMatrix();
effectTransformations();
- glBindVertexArray(_vaoHandle);
- int size;
- glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
- glm::mat4 mvpMatrix = pv * _model.getMatrix();
+ glBindVertexArray(_vaoHandle);
+ glm::mat4 mvpMatrix = proj_matrix * view_matrix * _model.getMatrix();
glUniformMatrix4fv(shader->uniform("mvp"), 1, GL_FALSE, glm::value_ptr(mvpMatrix));
+ glm::mat4 modelview = view_matrix * _model.getMatrix();
+ _model.glPopMatrix();
+ glUniform4fv(shader->uniform("LightLocation"), 1, glm::value_ptr(view_matrix * glm::vec4(50, 50, 50, 1)));
+ glUniformMatrix4fv(shader->uniform("ModelViewMatrix"), 1, GL_FALSE, glm::value_ptr(modelview));
+ glm::mat4 inverseModelView = glm::inverse(modelview);
+ glm::mat3 normalMatrix = glm::mat3(glm::transpose(inverseModelView));
+ glUniformMatrix3fv(shader->uniform("NormalMatrix"), 1, GL_FALSE, glm::value_ptr(normalMatrix));
+
if (ibo_used)
+ {
+ int size;
+ glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
glDrawElements(GL_TRIANGLES, size / sizeof(GLushort), GL_UNSIGNED_SHORT, 0);
+ }
else
glDrawArrays(GL_TRIANGLES, 0, 36);
- _model.glPopMatrix();
+
}
diff --git a/BaseGLProject/ColorCube.h b/BaseGLProject/ColorCube.h
index dedb46e..43fbea2 100644
--- a/BaseGLProject/ColorCube.h
+++ b/BaseGLProject/ColorCube.h
@@ -10,7 +10,7 @@ class ColorCube : public ADrawable
private:
GLuint _vaoHandle;
GLuint _iboHandle;
- GLuint _vbo_vertices, _vbo_colors;
+ GLuint _vbo_vertices, _vbo_colors, _vbo_normals;
bool ibo_used;
@@ -20,7 +20,7 @@ private:
public:
ColorCube(bool usingIBO);
- void draw(ShaderProgram *shader, glm::mat4x4 pv) override;
+ void draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) override;
DrawableType getType() override;
~ColorCube();
};
diff --git a/BaseGLProject/IDrawable.h b/BaseGLProject/IDrawable.h
index 254f661..2b20bc6 100644
--- a/BaseGLProject/IDrawable.h
+++ b/BaseGLProject/IDrawable.h
@@ -10,7 +10,9 @@ enum DrawableType
COLOR_CUBE,
CHECKERED_FLOOR,
WIRE_CUBE,
- LINE_SEGMENT
+ LINE_SEGMENT,
+ SPHERE,
+ TEAPOT
};
class IDrawable {
@@ -25,6 +27,6 @@ public:
virtual glm::vec3 getPosition() = 0;
virtual glm::vec4 translateToPivot(glm::vec3) = 0;
- virtual void draw(ShaderProgram *shader, glm::mat4x4 pv) = 0;
- virtual DrawableType getType() = 0;
+ virtual void draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) = 0;
+ virtual DrawableType getType() = 0;
};
\ No newline at end of file
diff --git a/BaseGLProject/LineSegment.cpp b/BaseGLProject/LineSegment.cpp
index 2b1989f..4c6dcfe 100644
--- a/BaseGLProject/LineSegment.cpp
+++ b/BaseGLProject/LineSegment.cpp
@@ -47,11 +47,11 @@ LineSegment::LineSegment()
setup();
}
-void LineSegment::draw(ShaderProgram *shader, glm::mat4x4 pv)
+void LineSegment::draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix)
{
_model.glPushMatrix();
effectTransformations();
- glm::mat4 mvpMatrix = pv * _model.getMatrix();
+ glm::mat4 mvpMatrix = proj_matrix * view_matrix * _model.getMatrix();
glUniformMatrix4fv(shader->uniform("mvp"), 1, GL_FALSE, glm::value_ptr(mvpMatrix));
glLineWidth(4);
glBindVertexArray(_vaoHandle);
diff --git a/BaseGLProject/LineSegment.h b/BaseGLProject/LineSegment.h
index 5b61d26..7be567c 100644
--- a/BaseGLProject/LineSegment.h
+++ b/BaseGLProject/LineSegment.h
@@ -25,7 +25,7 @@ public:
LineSegment();
- void draw(ShaderProgram *shader, glm::mat4x4 pv) override;
+ void draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) override;
DrawableType getType() override;
~LineSegment();
diff --git a/BaseGLProject/MyGLWindow.cpp b/BaseGLProject/MyGLWindow.cpp
index 1dba369..0c1cd40 100644
--- a/BaseGLProject/MyGLWindow.cpp
+++ b/BaseGLProject/MyGLWindow.cpp
@@ -1,6 +1,6 @@
#include
#include "MyGlWindow.h"
-
+//Getting the projection matrix
glm::mat4x4 perspective(float fovy, float aspect, float near, float far)
{
float fovy2 = glm::tan(fovy / 2);
@@ -57,31 +57,19 @@ void MyGlWindow::setBgColor(float bgColor[3])
void MyGlWindow::setup()
{
- _shaderProgram = new ShaderProgram();
- _shaderProgram->initFromFiles("simple.vert", "simple.frag");
+ _staticShader = new ShaderProgram();
+ _staticShader->initFromFiles("simple.vert", "simple.frag");
+ _lightShader = new ShaderProgram();
+ _lightShader->initFromFiles("light.vert", "simple.frag");
- _static_drawables.emplace_back(new CheckeredFloor(50, 16));
- _static_drawables.push_back(new ColorCube(true));
- _static_drawables.back()->addTranslation(glm::vec4(-2, 1.1f, 0, 0));
- _static_drawables.push_back(new ColorCube(false));
- _static_drawables.back()->addTranslation(glm::vec4(2, 1.1f, 0, 0));
-}
-
-void MyGlWindow::setViewFromBox(glm::vec3 &eye, glm::vec3 &look, glm::vec3 &up)
-{
- glm::vec4 cube_base_position = { 8, 7.01, 0 , 1.0f};
- Model model;
-
- cube_base_position.x = 7 - (floatValues["box_horizontal"] * 6);
- cube_base_position.y = 7 - (floatValues["box_vertical"] * 6);
-
- model.glPushMatrix();
- model.glTranslate(-8, 2, 0);
- model.glRotate(floatValues["boom_rotation"], 0, -1, 0);
- model.glTranslate(8, -2, 0);
-
-
- eye = cube_base_position * model.getMatrix();
+ _static_drawables.emplace_back(new CheckeredFloor(50, 16));
+ _light_drawables.push_back(new ColorCube(false));
+ _light_drawables.back()->addTranslation(glm::vec4(2, 1.1f, 0, 0));
+ _light_drawables.push_back(new Sphere(1, 100, 100));
+ _light_drawables.back()->addTranslation(glm::vec4(-2, 1.1f, 0, 0));
+ _light_drawables.push_back(new VBOTeapot(64, glm::identity()));
+ _light_drawables.back()->addTranslation(glm::vec4(2, 3, -7, 0));
+ _light_drawables.back()->addRotation(glm::vec4(1, 0, 0, -90));
}
void MyGlWindow::draw()
@@ -91,47 +79,48 @@ void MyGlWindow::draw()
glViewport(0, 0, m_width, m_height);
glEnable(GL_DEPTH_TEST);
- _shaderProgram->use();
-
glm::vec3 eye(viewer.getViewPoint().x, viewer.getViewPoint().y, viewer.getViewPoint().z);
glm::vec3 look(viewer.getViewCenter().x, viewer.getViewCenter().y, viewer.getViewCenter().z);
- glm::vec3 up(viewer.getUpVector().x, viewer.getUpVector().y, viewer.getUpVector().z);
+ glm::vec3 up(viewer.getUpVector().x, viewer.getUpVector().y, viewer.getUpVector().z);
glm::mat4 view = lookAt(eye, look, up); //Calculate view matrix from paramters of m_viewer
glm::mat4 projection = perspective(45.0f, m_width / m_height, 0.1f, 500.0f);
- _shaderProgram->addUniform("mvp");
+ _staticShader->use();
- for (ADrawable *drawable : _static_drawables)
- drawable->draw(_shaderProgram, projection * view);
-
- for (ADrawable *drawable : _crane_boom)
- {
- glm::vec4 t = drawable->translateToPivot(glm::vec3(0, 9.01, 0));
- drawable->addRotation(glm::vec4(0, 1, 0, floatValues["boom_rotation"]));
- drawable->addTranslation(t);
-
- if (drawable->getType() == COLOR_CUBE)
- drawable->addTranslation(glm::vec4(floatValues["box_horizontal"] * -6.01,
- floatValues["box_vertical"] * -6.01, 0 ,0));
- if (drawable->getType() == LINE_SEGMENT)
- {
- drawable->addTranslation(glm::vec4(floatValues["box_horizontal"] * -6.01 , floatValues["box_vertical"] * -4.01, 0, 0));
- drawable->addScaling(glm::vec4(0, floatValues["box_vertical"] * 4.01, 0, 0));
- }
-
- if (!view_from_box || (drawable->getType() != COLOR_CUBE && drawable->getType() != LINE_SEGMENT))
- drawable->draw(_shaderProgram, projection * view);
-
- if (drawable->getType() == COLOR_CUBE)
- drawable->removeLastTransformations(1);
- else if (drawable->getType() == LINE_SEGMENT)
- drawable->removeLastTransformations(2);
-
- drawable->removeLastTransformations(3);
-
- }
+ _staticShader->addUniform("mvp");
- _shaderProgram->disable();
+ for (ADrawable *drawable : _static_drawables)
+ drawable->draw(_staticShader, projection, view);
+
+ _staticShader->disable();
+
+ _lightShader->use();
+
+ _lightShader->addUniform("mvp");
+ _lightShader->addUniform("LightLocation"); //Light Position to camera coordinates : vec4
+
+ _lightShader->addUniform("Kd"); //Diffuse Object Color :vec3
+ glUniform3fv(_lightShader->uniform("Kd"), 1, glm::value_ptr(glm::vec3(1, 1, 0)));
+ _lightShader->addUniform("Ld"); //Diffuse Light Color : vec3
+ glUniform3fv(_lightShader->uniform("Ld"), 1, glm::value_ptr(glm::vec3(1, 1, 1)));
+
+ _lightShader->addUniform("Ka"); //Diffuse Object Color :vec3
+ glUniform3fv(_lightShader->uniform("Ka"), 1, glm::value_ptr(glm::vec3(0.2, 0.2, 0)));
+ _lightShader->addUniform("La"); //Diffuse Light Color : vec3
+ glUniform3fv(_lightShader->uniform("La"), 1, glm::value_ptr(glm::vec3(1, 1, 1)));
+
+ _lightShader->addUniform("Ks"); //Diffuse Object Color :vec3
+ glUniform3fv(_lightShader->uniform("Ks"), 1, glm::value_ptr(glm::vec3(0.3, 0.3, 0)));
+ _lightShader->addUniform("Ls"); //Diffuse Light Color : vec3
+ glUniform3fv(_lightShader->uniform("Ls"), 1, glm::value_ptr(glm::vec3(1, 1, 1)));
+
+ _lightShader->addUniform("NormalMatrix"); //Refer next slide : mat3
+ _lightShader->addUniform("ModelViewMatrix"); //View*Model : mat4
+
+ for (ADrawable *drawable : _light_drawables)
+ drawable->draw(_lightShader, projection, view);
+
+ _lightShader->disable();
}
void MyGlWindow::AddDrawable(ADrawable *d)
diff --git a/BaseGLProject/MyGLWindow.h b/BaseGLProject/MyGLWindow.h
index 972014d..7962781 100644
--- a/BaseGLProject/MyGLWindow.h
+++ b/BaseGLProject/MyGLWindow.h
@@ -12,6 +12,8 @@
#include "CheckeredFloor.h"
#include "WireCube.h"
#include "LineSegment.h"
+#include "Sphere.h"
+#include "vboteapot.h"
struct vertexAttr {
GLfloat posX, posY, posZ;
@@ -28,13 +30,13 @@ public:
void setBgColor(float bgColor[3]);
std::map floatValues;
- bool view_from_box = false;
void AddDrawable(ADrawable *);
void resize(int w, int h);
Viewer viewer;
private:
- ShaderProgram *_shaderProgram;
+ ShaderProgram *_staticShader;
+ ShaderProgram *_lightShader;
int m_width;
int m_height;
@@ -44,8 +46,7 @@ private:
GLuint _iboHandle;
std::vector _static_drawables;
-
- std::vector _crane_boom;
+ std::vector _light_drawables;
void setup();
void setViewFromBox(glm::vec3 &eye, glm::vec3 &look, glm::vec3 &up);
diff --git a/BaseGLProject/Source.cpp b/BaseGLProject/Source.cpp
index 4f8c3ac..c96f62c 100644
--- a/BaseGLProject/Source.cpp
+++ b/BaseGLProject/Source.cpp
@@ -173,31 +173,14 @@ int loop(GLFWwindow *window)
if (ImGui::Begin("First Window"))
{
- ImGui::SetWindowPos(ImVec2(20, 20));
-
- static float box_horizontal = .0f;
- ImGui::SliderFloat("Box Horizontal", &box_horizontal, 0, 1);
- glWin.floatValues["box_horizontal"] = box_horizontal;
-
- static float box_vertical = .0f;
- ImGui::SliderFloat("Box Vertical", &box_vertical, 0, 1);
- glWin.floatValues["box_vertical"] = box_vertical;
-
- static float boom_rotation = .0f;
- ImGui::SliderFloat("Boom rotation", &boom_rotation, -180, 180);
- glWin.floatValues["boom_rotation"] = boom_rotation;
-
- static int box_view;
- ImGui::RadioButton("Default", &box_view, 0); ImGui::SameLine();
- ImGui::RadioButton("Box", &box_view, 1);
- glWin.view_from_box = box_view;
+ ImGui::SetWindowPos(ImVec2(20, 20));
static float bgColor[3] = { .3f, .3f, .3f };
ImGui::ColorEdit3("Background", bgColor, 0);
glWin.setBgColor(bgColor);
ImGui::End();
- }
+ }
glfwSwapBuffers(window);
glWin.draw();
diff --git a/BaseGLProject/Sphere.cpp b/BaseGLProject/Sphere.cpp
new file mode 100644
index 0000000..33ca388
--- /dev/null
+++ b/BaseGLProject/Sphere.cpp
@@ -0,0 +1,191 @@
+#include "Sphere.h"
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+Sphere::Sphere()
+{
+
+}
+
+
+Sphere::~Sphere()
+{
+}
+
+
+
+Sphere::Sphere(float rad, GLuint sl, GLuint st) :
+radius(rad), slices(sl), stacks(st)
+{
+
+ nVerts = (slices + 1) * (stacks + 1);
+ elements = (slices * 2 * (stacks - 1)) * 3;
+
+ // Verts
+ float * v = new float[3 * nVerts];
+ // Normals
+ float * n = new float[3 * nVerts];
+ // Tex coords
+ float * tex = new float[2 * nVerts]; //we don't use it now
+ // Index
+ unsigned int * el = new unsigned int[elements]; //index
+
+ // Generate the vertex data
+ generateVerts(v, n, tex, el);
+
+
+
+ //create vao, vbo and ibo here... (We didn't use std::vector here...)
+
+ glGenVertexArrays(1, &VAO);
+ glBindVertexArray(VAO);
+
+ glGenBuffers(1, &VBO_position);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO_position);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * nVerts, v, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(
+ 0, //attr number = 0
+ 3,
+ GL_FLOAT,
+ GL_FALSE,
+ 0,
+ (void*)0);
+ glEnableVertexAttribArray(0); //attr number = 0
+
+ glGenBuffers(1, &VBO_normal);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO_normal);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * nVerts, n, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(
+ 1,
+ 3,
+ GL_FLOAT,
+ GL_FALSE,
+ 0,
+ (void*)0);
+ glEnableVertexAttribArray(1);
+
+ glGenBuffers(1, &VBO_tex);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO_tex);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 2 * nVerts, tex, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(
+ 2,
+ 3,
+ GL_FLOAT,
+ GL_FALSE,
+ 0,
+ (void*)0);
+ glEnableVertexAttribArray(2);
+
+
+ glGenBuffers(1, &IBO);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements * sizeof(GLuint), el, GL_STATIC_DRAW);
+
+ glBindVertexArray(0);
+
+ delete[] v;
+ delete[] n;
+ delete[] el;
+ delete[] tex;
+
+}
+
+void Sphere::draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix)
+{
+ _model.glPushMatrix();
+ effectTransformations();
+ glBindVertexArray(VAO);
+ glm::mat4 mvpMatrix = proj_matrix * view_matrix * _model.getMatrix();
+ glUniformMatrix4fv(shader->uniform("mvp"), 1, GL_FALSE, glm::value_ptr(mvpMatrix));
+ glm::mat4 modelview = view_matrix * _model.getMatrix();
+ glUniform4fv(shader->uniform("LightLocation"), 1, glm::value_ptr(view_matrix * glm::vec4(50, 50, 50, 1)));
+ glUniformMatrix4fv(shader->uniform("ModelViewMatrix"), 1, GL_FALSE, glm::value_ptr(modelview));
+ glm::mat4 inverseModelView = glm::inverse(modelview);
+ glm::mat3 normalMatrix = glm::mat3(glm::transpose(inverseModelView));
+ glUniformMatrix3fv(shader->uniform("NormalMatrix"), 1, GL_FALSE, glm::value_ptr(normalMatrix));
+
+ int size;
+ glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
+ glDrawElements(GL_TRIANGLES, size / sizeof(GLuint), GL_UNSIGNED_INT, 0);
+
+ _model.glPopMatrix();
+
+}
+
+void Sphere::generateVerts(float * verts, float * norms, float * tex,
+ unsigned int * el)
+{
+ // Generate positions and normals
+ GLfloat theta, phi;
+ GLfloat thetaFac = glm::two_pi() / slices;
+ GLfloat phiFac = glm::pi() / stacks;
+ GLfloat nx, ny, nz, s, t;
+ GLuint idx = 0, tIdx = 0;
+ for (GLuint i = 0; i <= slices; i++) {
+ theta = i * thetaFac;
+ s = (GLfloat)i / slices;
+ for (GLuint j = 0; j <= stacks; j++) {
+ phi = j * phiFac;
+ t = (GLfloat)j / stacks;
+ nx = sinf(phi) * cosf(theta);
+ ny = sinf(phi) * sinf(theta);
+ nz = cosf(phi);
+ verts[idx] = radius * nx; verts[idx + 1] = radius * ny; verts[idx + 2] = radius * nz;
+ norms[idx] = nx; norms[idx + 1] = ny; norms[idx + 2] = nz;
+ idx += 3;
+
+ tex[tIdx] = s;
+ tex[tIdx + 1] = t;
+ tIdx += 2;
+ }
+ }
+
+ // Generate the element list
+ idx = 0;
+ for (GLuint i = 0; i < slices; i++) {
+ GLuint stackStart = i * (stacks + 1);
+ GLuint nextStackStart = (i + 1) * (stacks + 1);
+ for (GLuint j = 0; j < stacks; j++) {
+ if (j == 0) {
+ el[idx] = stackStart;
+ el[idx + 1] = stackStart + 1;
+ el[idx + 2] = nextStackStart + 1;
+ idx += 3;
+ }
+ else if (j == stacks - 1) {
+ el[idx] = stackStart + j;
+ el[idx + 1] = stackStart + j + 1;
+ el[idx + 2] = nextStackStart + j;
+ idx += 3;
+ }
+ else {
+ el[idx] = stackStart + j;
+ el[idx + 1] = stackStart + j + 1;
+ el[idx + 2] = nextStackStart + j + 1;
+ el[idx + 3] = nextStackStart + j;
+ el[idx + 4] = stackStart + j;
+ el[idx + 5] = nextStackStart + j + 1;
+ idx += 6;
+ }
+ }
+ }
+}
+
+DrawableType Sphere::getType()
+{
+ return DrawableType::SPHERE;
+}
+
+int Sphere::getVertexArrayHandle()
+{
+ return this->VAO;
+}
+
diff --git a/BaseGLProject/Sphere.h b/BaseGLProject/Sphere.h
new file mode 100644
index 0000000..051c4bb
--- /dev/null
+++ b/BaseGLProject/Sphere.h
@@ -0,0 +1,45 @@
+#ifndef ___SPHERE_H
+#define ___SPHERE_H
+
+#include "GL/glew.h"
+#include
+#include
+
+#include
+
+#include "ADrawable.h"
+
+#include "Loader.h"
+
+
+
+class Sphere : public ADrawable
+{
+public:
+ Sphere();
+ Sphere(float rad, GLuint sl, GLuint st);
+ ~Sphere();
+
+ void draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix);
+ int getVertexArrayHandle();
+
+ GLuint VAO, VBO_position, VBO_normal, VBO_tex, IBO;
+
+
+
+private:
+ GLuint nVerts, elements;
+ float radius;
+ GLuint slices, stacks;
+
+ void generateVerts(float *, float *, float *, unsigned int *);
+
+
+
+ // Inherited via ADrawable
+ virtual DrawableType getType() override;
+
+};
+
+
+#endif
diff --git a/BaseGLProject/WireCube.cpp b/BaseGLProject/WireCube.cpp
index 0d65646..184ac58 100644
--- a/BaseGLProject/WireCube.cpp
+++ b/BaseGLProject/WireCube.cpp
@@ -43,11 +43,11 @@ WireCube::WireCube()
setup();
}
-void WireCube::draw(ShaderProgram * shader, glm::mat4x4 pv)
+void WireCube::draw(ShaderProgram * shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix)
{
_model.glPushMatrix();
effectTransformations();
- glm::mat4 mvpMatrix = pv * _model.getMatrix();
+ glm::mat4 mvpMatrix = proj_matrix * view_matrix * _model.getMatrix();
glUniformMatrix4fv(shader->uniform("mvp"), 1, GL_FALSE, glm::value_ptr(mvpMatrix));
glLineWidth(2);
diff --git a/BaseGLProject/WireCube.h b/BaseGLProject/WireCube.h
index f02955c..e65e13c 100644
--- a/BaseGLProject/WireCube.h
+++ b/BaseGLProject/WireCube.h
@@ -19,7 +19,7 @@ private:
public:
WireCube();
- void draw(ShaderProgram *shader, glm::mat4x4 pv) override;
+ void draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) override;
DrawableType getType() override;
~WireCube();
diff --git a/BaseGLProject/imgui.ini b/BaseGLProject/imgui.ini
index 20b6a0c..7a9553e 100644
--- a/BaseGLProject/imgui.ini
+++ b/BaseGLProject/imgui.ini
@@ -45,6 +45,6 @@ Collapsed=0
[Window][First Window]
Pos=20,20
-Size=350,150
+Size=322,75
Collapsed=0
diff --git a/BaseGLProject/light.vert b/BaseGLProject/light.vert
new file mode 100644
index 0000000..2bbdae2
--- /dev/null
+++ b/BaseGLProject/light.vert
@@ -0,0 +1,42 @@
+#version 430
+
+layout(location=0) in vec3 coord3d;
+layout(location=1) in vec3 v_normal;
+layout(location=2) in vec3 v_color;
+
+out vec3 f_color;
+
+uniform mat4 mvp;
+uniform vec4 LightLocation;
+
+uniform vec3 Kd;
+uniform vec3 Ld;
+
+uniform vec3 Ka;
+uniform vec3 La;
+
+uniform vec3 Ks;
+uniform vec3 Ls;
+
+
+uniform mat3 NormalMatrix;
+uniform mat4 ModelViewMatrix;
+
+
+void main(void)
+{
+ vec3 fNormal = normalize(NormalMatrix * v_normal);
+ vec4 pos = ModelViewMatrix * vec4(coord3d, 1.0);
+
+ vec3 L = normalize(LightLocation.xyz - pos.xyz);
+ vec3 N = fNormal;
+ vec3 V = normalize(-pos.xyz);
+ vec3 R = reflect(-L, N);
+
+ vec3 diffuse = Kd * Ld * max(dot(L, N), 0.0);
+ vec3 ambient = Ka * La;
+ vec3 specular = Ks * Ls * pow(max(dot(L, N), 0.0), 50.0);
+
+ f_color = diffuse + ambient + specular;
+ gl_Position = mvp * vec4(coord3d, 1.0f);
+}
diff --git a/BaseGLProject/simple.vert b/BaseGLProject/simple.vert
index 365c54b..a377d01 100644
--- a/BaseGLProject/simple.vert
+++ b/BaseGLProject/simple.vert
@@ -11,4 +11,4 @@ void main(void)
{
f_color = v_color;
gl_Position = mvp * vec4(coord3d, 1.0f);
-}
+}
\ No newline at end of file
diff --git a/BaseGLProject/teapotdata.h b/BaseGLProject/teapotdata.h
new file mode 100644
index 0000000..606c7b4
--- /dev/null
+++ b/BaseGLProject/teapotdata.h
@@ -0,0 +1,206 @@
+#ifndef TEAPOTDATA_H
+#define TEAPOTDATA_H
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/**
+(c) Copyright 1993, Silicon Graphics, Inc.
+
+ALL RIGHTS RESERVED
+
+Permission to use, copy, modify, and distribute this software
+for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that
+both the copyright notice and this permission notice appear in
+supporting documentation, and that the name of Silicon
+Graphics, Inc. not be used in advertising or publicity
+pertaining to distribution of the software without specific,
+written prior permission.
+
+THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
+"AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
+OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
+EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
+ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
+INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
+SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
+NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
+OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+US Government Users Restricted Rights
+
+Use, duplication, or disclosure by the Government is subject to
+restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+(c)(1)(ii) of the Rights in Technical Data and Computer
+Software clause at DFARS 252.227-7013 and/or in similar or
+successor clauses in the FAR or the DOD or NASA FAR
+Supplement. Unpublished-- rights reserved under the copyright
+laws of the United States. Contractor/manufacturer is Silicon
+Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
+94039-7311.
+
+OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+*/
+
+/* Rim, body, lid, and bottom data must be reflected in x and
+ y; handle and spout data across the y axis only. */
+
+namespace Teapot {
+static int patchdata[][16] =
+{
+ /* rim */
+ {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
+ /* body */
+ {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27},
+ {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40},
+ /* lid */
+ {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3,},
+ {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117},
+ /* bottom */
+ {118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37},
+ /* handle */
+ {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56},
+ {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67},
+ /* spout */
+ {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83},
+ {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95}
+};
+
+static float cpdata[][3] =
+{
+ {0.2f, 0.f, 2.7f},
+ {0.2f, -0.112f, 2.7f},
+ {0.112f, -0.2f, 2.7f},
+ {0.f, -0.2f, 2.7f},
+ {1.3375f, 0.f, 2.53125f},
+ {1.3375f, -0.749f, 2.53125f},
+ {0.749f, -1.3375f, 2.53125f},
+ {0.f, -1.3375f, 2.53125f},
+ {1.4375f, 0.f, 2.53125f},
+ {1.4375f, -0.805f, 2.53125f},
+ {0.805f, -1.4375f, 2.53125f},
+ {0.f, -1.4375f, 2.53125f},
+ {1.5f, 0.f, 2.4f},
+ {1.5f, -0.84f, 2.4f},
+ {0.84f, -1.5f, 2.4f},
+ {0.f, -1.5f, 2.4f},
+ {1.75f, 0.f, 1.875f},
+ {1.75f, -0.98f, 1.875f},
+ {0.98f, -1.75f, 1.875f},
+ {0.f, -1.75f, 1.875f},
+ {2.f, 0.f, 1.35f},
+ {2.f, -1.12f, 1.35f},
+ {1.12f, -2.f, 1.35f},
+ {0.f, -2.f, 1.35f},
+ {2.f, 0.f, 0.9f},
+ {2.f, -1.12f, 0.9f},
+ {1.12f, -2.f, 0.9f},
+ {0.f, -2.f, 0.9f},
+ {-2.f, 0.f, 0.9f},
+ {2.f, 0.f, 0.45f},
+ {2.f, -1.12f, 0.45f},
+ {1.12f, -2.f, 0.45f},
+ {0.f, -2.f, 0.45f},
+ {1.5f, 0.f, 0.225f},
+ {1.5f, -0.84f, 0.225f},
+ {0.84f, -1.5f, 0.225f},
+ {0.f, -1.5f, 0.225f},
+ {1.5f, 0.f, 0.15f},
+ {1.5f, -0.84f, 0.15f},
+ {0.84f, -1.5f, 0.15f},
+ {0.f, -1.5f, 0.15f},
+ {-1.6f, 0.f, 2.025f},
+ {-1.6f, -0.3f, 2.025f},
+ {-1.5f, -0.3f, 2.25f},
+ {-1.5f, 0.f, 2.25f},
+ {-2.3f, 0.f, 2.025f},
+ {-2.3f, -0.3f, 2.025f},
+ {-2.5f, -0.3f, 2.25f},
+ {-2.5f, 0.f, 2.25f},
+ {-2.7f, 0.f, 2.025f},
+ {-2.7f, -0.3f, 2.025f},
+ {-3.f, -0.3f, 2.25f},
+ {-3.f, 0.f, 2.25f},
+ {-2.7f, 0.f, 1.8f},
+ {-2.7f, -0.3f, 1.8f},
+ {-3.f, -0.3f, 1.8f},
+ {-3.f, 0.f, 1.8f},
+ {-2.7f, 0.f, 1.575f},
+ {-2.7f, -0.3f, 1.575f},
+ {-3.f, -0.3f, 1.35f},
+ {-3.f, 0.f, 1.35f},
+ {-2.5f, 0.f, 1.125f},
+ {-2.5f, -0.3f, 1.125f},
+ {-2.65f, -0.3f, 0.9375f},
+ {-2.65f, 0.f, 0.9375f},
+ {-2.f, -0.3f, 0.9f},
+ {-1.9f, -0.3f, 0.6f},
+ {-1.9f, 0.f, 0.6f},
+ {1.7f, 0.f, 1.425f},
+ {1.7f, -0.66f, 1.425f},
+ {1.7f, -0.66f, 0.6f},
+ {1.7f, 0.f, 0.6f},
+ {2.6f, 0.f, 1.425f},
+ {2.6f, -0.66f, 1.425f},
+ {3.1f, -0.66f, 0.825f},
+ {3.1f, 0.f, 0.825f},
+ {2.3f, 0.f, 2.1f},
+ {2.3f, -0.25f, 2.1f},
+ {2.4f, -0.25f, 2.025f},
+ {2.4f, 0.f, 2.025f},
+ {2.7f, 0.f, 2.4f},
+ {2.7f, -0.25f, 2.4f},
+ {3.3f, -0.25f, 2.4f},
+ {3.3f, 0.f, 2.4f},
+ {2.8f, 0.f, 2.475f},
+ {2.8f, -0.25f, 2.475f},
+ {3.525f, -0.25f, 2.49375f},
+ {3.525f, 0.f, 2.49375f},
+ {2.9f, 0.f, 2.475f},
+ {2.9f, -0.15f, 2.475f},
+ {3.45f, -0.15f, 2.5125f},
+ {3.45f, 0.f, 2.5125f},
+ {2.8f, 0.f, 2.4f},
+ {2.8f, -0.15f, 2.4f},
+ {3.2f, -0.15f, 2.4f},
+ {3.2f, 0.f, 2.4f},
+ {0.f, 0.f, 3.15f},
+ {0.8f, 0.f, 3.15f},
+ {0.8f, -0.45f, 3.15f},
+ {0.45f, -0.8f, 3.15f},
+ {0.f, -0.8f, 3.15f},
+ {0.f, 0.f, 2.85f},
+ {1.4f, 0.f, 2.4f},
+ {1.4f, -0.784f, 2.4f},
+ {0.784f, -1.4f, 2.4f},
+ {0.f, -1.4f, 2.4f},
+ {0.4f, 0.f, 2.55f},
+ {0.4f, -0.224f, 2.55f},
+ {0.224f, -0.4f, 2.55f},
+ {0.f, -0.4f, 2.55f},
+ {1.3f, 0.f, 2.55f},
+ {1.3f, -0.728f, 2.55f},
+ {0.728f, -1.3f, 2.55f},
+ {0.f, -1.3f, 2.55f},
+ {1.3f, 0.f, 2.4f},
+ {1.3f, -0.728f, 2.4f},
+ {0.728f, -1.3f, 2.4f},
+ {0.f, -1.3f, 2.4f},
+ {0.f, 0.f, 0.f},
+ {1.425f, -0.798f, 0.f},
+ {1.5f, 0.f, 0.075f},
+ {1.425f, 0.f, 0.f},
+ {0.798f, -1.425f, 0.f},
+ {0.f, -1.5f, 0.075f},
+ {0.f, -1.425f, 0.f},
+ {1.5f, -0.84f, 0.075f},
+ {0.84f, -1.5f, 0.075f}
+};
+
+}
+
+#endif // TEAPOTDATA_H
diff --git a/BaseGLProject/vboteapot.cpp b/BaseGLProject/vboteapot.cpp
new file mode 100644
index 0000000..06a55d5
--- /dev/null
+++ b/BaseGLProject/vboteapot.cpp
@@ -0,0 +1,326 @@
+#include "vboteapot.h"
+#include "teapotdata.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+
+
+//set grid = 64, lidTransform = 4x4 identity matrix
+VBOTeapot::VBOTeapot(int grid, mat4 lidTransform)
+{
+ int verts = 32 * (grid + 1) * (grid + 1);
+ faces = grid * grid * 32;
+
+
+ float * v = new float[ verts * 3 ]; //vertex positions : vec3
+ float * n = new float[ verts * 3 ]; //vertex normals : vec3
+ float * tc = new float[ verts * 2 ]; //texture coordinates : vec2 (we don't use it at this point)
+ unsigned int * el = new unsigned int[faces * 6]; //indices for IBO
+
+ generatePatches(v, n, tc, el, grid);
+
+
+
+
+ glGenVertexArrays(1, &VAO);
+ glBindVertexArray(VAO);
+
+ glGenBuffers(1, &VBO_position);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO_position);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * verts, v, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(
+ 0, //attr number = 0
+ 3,
+ GL_FLOAT,
+ GL_FALSE,
+ 0,
+ (void*)0);
+ glEnableVertexAttribArray(0); //attr number = 0
+
+ glGenBuffers(1, &VBO_normal);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO_normal);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * verts, n, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(
+ 1,
+ 3,
+ GL_FLOAT,
+ GL_FALSE,
+ 0,
+ (void*)0);
+ glEnableVertexAttribArray(1);
+
+ glGenBuffers(1, &VBO_tex);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO_tex);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 2 * verts, tc, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(
+ 2,
+ 3,
+ GL_FLOAT,
+ GL_FALSE,
+ 0,
+ (void*)0);
+ glEnableVertexAttribArray(2);
+
+
+ glGenBuffers(1, &IBO);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, faces * 6 * sizeof(GLuint), el, GL_STATIC_DRAW);
+
+ glBindVertexArray(0);
+
+
+ delete [] v;
+ delete [] n;
+ delete [] el;
+ delete [] tc;
+
+
+}
+
+void VBOTeapot::draw(ShaderProgram * shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix)
+{
+ _model.glPushMatrix();
+ effectTransformations();
+ glBindVertexArray(VAO);
+ glm::mat4 mvpMatrix = proj_matrix * view_matrix * _model.getMatrix();
+ glUniformMatrix4fv(shader->uniform("mvp"), 1, GL_FALSE, glm::value_ptr(mvpMatrix));
+ glm::mat4 modelview = view_matrix * _model.getMatrix();
+ glUniform4fv(shader->uniform("LightLocation"), 1, glm::value_ptr(view_matrix * glm::vec4(50, 50, 50, 1)));
+ glUniformMatrix4fv(shader->uniform("ModelViewMatrix"), 1, GL_FALSE, glm::value_ptr(modelview));
+ glm::mat4 inverseModelView = glm::inverse(modelview);
+ glm::mat3 normalMatrix = glm::mat3(glm::transpose(inverseModelView));
+ glUniformMatrix3fv(shader->uniform("NormalMatrix"), 1, GL_FALSE, glm::value_ptr(normalMatrix));
+
+ int size;
+ glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
+ glDrawElements(GL_TRIANGLES, size / sizeof(GLuint), GL_UNSIGNED_INT, 0);
+
+ _model.glPopMatrix();
+
+}
+
+DrawableType VBOTeapot::getType()
+{
+ return DrawableType::TEAPOT;
+}
+
+void VBOTeapot::generatePatches(float * v, float * n, float * tc, unsigned int* el, int grid) {
+ float * B = new float[4*(grid+1)]; // Pre-computed Bernstein basis functions
+ float * dB = new float[4*(grid+1)]; // Pre-computed derivitives of basis functions
+
+ int idx = 0, elIndex = 0, tcIndex = 0;
+
+ // Pre-compute the basis functions (Bernstein polynomials)
+ // and their derivatives
+ computeBasisFunctions(B, dB, grid);
+
+ // Build each patch
+ // The rim
+ buildPatchReflect(0, B, dB, v, n, tc, el, idx, elIndex, tcIndex, grid, true, true);
+ // The body
+ buildPatchReflect(1, B, dB, v, n, tc, el, idx, elIndex, tcIndex, grid, true, true);
+ buildPatchReflect(2, B, dB, v, n, tc, el, idx, elIndex, tcIndex, grid, true, true);
+ // The lid
+ buildPatchReflect(3, B, dB, v, n, tc, el, idx, elIndex, tcIndex, grid, true, true);
+ buildPatchReflect(4, B, dB, v, n, tc, el, idx, elIndex, tcIndex, grid, true, true);
+ // The bottom
+ buildPatchReflect(5, B, dB, v, n, tc, el, idx, elIndex, tcIndex, grid, true, true);
+ // The handle
+ buildPatchReflect(6, B, dB, v, n, tc, el, idx, elIndex, tcIndex, grid, false, true);
+ buildPatchReflect(7, B, dB, v, n, tc, el, idx, elIndex, tcIndex, grid, false, true);
+ // The spout
+ buildPatchReflect(8, B, dB, v, n, tc, el, idx, elIndex, tcIndex, grid, false, true);
+ buildPatchReflect(9, B, dB, v, n, tc, el, idx, elIndex, tcIndex, grid, false, true);
+
+ delete [] B;
+ delete [] dB;
+}
+
+void VBOTeapot::moveLid(int grid, float *v, mat4 lidTransform) {
+
+ int start = 3 * 12 * (grid+1) * (grid+1);
+ int end = 3 * 20 * (grid+1) * (grid+1);
+
+ for( int i = start; i < end; i+=3 )
+ {
+ vec4 vert = vec4(v[i], v[i+1], v[i+2], 1.0f );
+ vert = lidTransform * vert;
+ v[i] = vert.x;
+ v[i+1] = vert.y;
+ v[i+2] = vert.z;
+ }
+}
+
+void VBOTeapot::buildPatchReflect(int patchNum,
+ float *B, float *dB,
+ float *v, float *n,
+ float *tc, unsigned int *el,
+ int &index, int &elIndex, int &tcIndex, int grid,
+ bool reflectX, bool reflectY)
+{
+ vec3 patch[4][4];
+ vec3 patchRevV[4][4];
+ getPatch(patchNum, patch, false);
+ getPatch(patchNum, patchRevV, true);
+
+ // Patch without modification
+ buildPatch(patch, B, dB, v, n, tc, el,
+ index, elIndex, tcIndex, grid, mat3(1.0f), true);
+
+ // Patch reflected in x
+ if( reflectX ) {
+ buildPatch(patchRevV, B, dB, v, n, tc, el,
+ index, elIndex, tcIndex, grid, mat3(vec3(-1.0f, 0.0f, 0.0f),
+ vec3(0.0f, 1.0f, 0.0f),
+ vec3(0.0f, 0.0f, 1.0f) ), false );
+ }
+
+ // Patch reflected in y
+ if( reflectY ) {
+ buildPatch(patchRevV, B, dB, v, n, tc, el,
+ index, elIndex, tcIndex, grid, mat3(vec3(1.0f, 0.0f, 0.0f),
+ vec3(0.0f, -1.0f, 0.0f),
+ vec3(0.0f, 0.0f, 1.0f) ), false );
+ }
+
+ // Patch reflected in x and y
+ if( reflectX && reflectY ) {
+ buildPatch(patch, B, dB, v, n, tc, el,
+ index, elIndex, tcIndex, grid, mat3(vec3(-1.0f, 0.0f, 0.0f),
+ vec3(0.0f, -1.0f, 0.0f),
+ vec3(0.0f, 0.0f, 1.0f) ), true );
+ }
+}
+
+void VBOTeapot::buildPatch(vec3 patch[][4],
+ float *B, float *dB,
+ float *v, float *n, float *tc,
+ unsigned int *el,
+ int &index, int &elIndex, int &tcIndex, int grid, mat3 reflect,
+ bool invertNormal)
+{
+ int startIndex = index / 3;
+ float tcFactor = 1.0f / grid;
+
+ for( int i = 0; i <= grid; i++ )
+ {
+ for( int j = 0 ; j <= grid; j++)
+ {
+ vec3 pt = reflect * evaluate(i,j,B,patch);
+ vec3 norm = reflect * evaluateNormal(i,j,B,dB,patch);
+ if( invertNormal )
+ norm = -norm;
+
+ v[index] = pt.x;
+ v[index+1] = pt.y;
+ v[index+2] = pt.z;
+
+ n[index] = norm.x;
+ n[index+1] = norm.y;
+ n[index+2] = norm.z;
+
+ tc[tcIndex] = i * tcFactor;
+ tc[tcIndex+1] = j * tcFactor;
+
+ index += 3;
+ tcIndex += 2;
+ }
+ }
+
+ for( int i = 0; i < grid; i++ )
+ {
+ int iStart = i * (grid+1) + startIndex;
+ int nextiStart = (i+1) * (grid+1) + startIndex;
+ for( int j = 0; j < grid; j++)
+ {
+ el[elIndex] = iStart + j;
+ el[elIndex+1] = nextiStart + j + 1;
+ el[elIndex+2] = nextiStart + j;
+
+ el[elIndex+3] = iStart + j;
+ el[elIndex+4] = iStart + j + 1;
+ el[elIndex+5] = nextiStart + j + 1;
+
+ elIndex += 6;
+ }
+ }
+}
+
+void VBOTeapot::getPatch( int patchNum, vec3 patch[][4], bool reverseV )
+{
+ for( int u = 0; u < 4; u++) { // Loop in u direction
+ for( int v = 0; v < 4; v++ ) { // Loop in v direction
+ if( reverseV ) {
+ patch[u][v] = vec3(
+ Teapot::cpdata[Teapot::patchdata[patchNum][u*4+(3-v)]][0],
+ Teapot::cpdata[Teapot::patchdata[patchNum][u*4+(3-v)]][1],
+ Teapot::cpdata[Teapot::patchdata[patchNum][u*4+(3-v)]][2]
+ );
+ } else {
+ patch[u][v] = vec3(
+ Teapot::cpdata[Teapot::patchdata[patchNum][u*4+v]][0],
+ Teapot::cpdata[Teapot::patchdata[patchNum][u*4+v]][1],
+ Teapot::cpdata[Teapot::patchdata[patchNum][u*4+v]][2]
+ );
+ }
+ }
+ }
+}
+
+void VBOTeapot::computeBasisFunctions( float * B, float * dB, int grid ) {
+ float inc = 1.0f / grid;
+ for( int i = 0; i <= grid; i++ )
+ {
+ float t = i * inc;
+ float tSqr = t * t;
+ float oneMinusT = (1.0f - t);
+ float oneMinusT2 = oneMinusT * oneMinusT;
+
+ B[i*4 + 0] = oneMinusT * oneMinusT2;
+ B[i*4 + 1] = 3.0f * oneMinusT2 * t;
+ B[i*4 + 2] = 3.0f * oneMinusT * tSqr;
+ B[i*4 + 3] = t * tSqr;
+
+ dB[i*4 + 0] = -3.0f * oneMinusT2;
+ dB[i*4 + 1] = -6.0f * t * oneMinusT + 3.0f * oneMinusT2;
+ dB[i*4 + 2] = -3.0f * tSqr + 6.0f * t * oneMinusT;
+ dB[i*4 + 3] = 3.0f * tSqr;
+ }
+}
+
+
+vec3 VBOTeapot::evaluate( int gridU, int gridV, float *B, vec3 patch[][4] )
+{
+ vec3 p(0.0f,0.0f,0.0f);
+ for( int i = 0; i < 4; i++) {
+ for( int j = 0; j < 4; j++) {
+ p += patch[i][j] * B[gridU*4+i] * B[gridV*4+j];
+ }
+ }
+ return p;
+}
+
+vec3 VBOTeapot::evaluateNormal( int gridU, int gridV, float *B, float *dB, vec3 patch[][4] )
+{
+ vec3 du(0.0f,0.0f,0.0f);
+ vec3 dv(0.0f,0.0f,0.0f);
+
+ for( int i = 0; i < 4; i++) {
+ for( int j = 0; j < 4; j++) {
+ du += patch[i][j] * dB[gridU*4+i] * B[gridV*4+j];
+ dv += patch[i][j] * B[gridU*4+i] * dB[gridV*4+j];
+ }
+ }
+ return glm::normalize( glm::cross( du, dv ) );
+}
diff --git a/BaseGLProject/vboteapot.h b/BaseGLProject/vboteapot.h
new file mode 100644
index 0000000..ab57a82
--- /dev/null
+++ b/BaseGLProject/vboteapot.h
@@ -0,0 +1,52 @@
+#ifndef VBOTEAPOT_H
+#define VBOTEAPOT_H
+
+
+
+
+#include
+#include
+#include
+#include "ADrawable.h"
+#include "Loader.h"
+
+using glm::vec4;
+using glm::vec3;
+using glm::mat3;
+using glm::mat4;
+
+class VBOTeapot : public ADrawable
+{
+private:
+ GLuint VAO, VBO_position, VBO_normal, VBO_tex, IBO;
+ unsigned int faces;
+
+ void generatePatches(float * v, float * n, float *tc, unsigned int* el, int grid);
+ void buildPatchReflect(int patchNum,
+ float *B, float *dB,
+ float *v, float *n, float *, unsigned int *el,
+ int &index, int &elIndex, int &, int grid,
+ bool reflectX, bool reflectY);
+ void buildPatch(vec3 patch[][4],
+ float *B, float *dB,
+ float *v, float *n,float *, unsigned int *el,
+ int &index, int &elIndex, int &, int grid, mat3 reflect, bool invertNormal);
+ void getPatch( int patchNum, vec3 patch[][4], bool reverseV );
+
+ void computeBasisFunctions( float * B, float * dB, int grid );
+ vec3 evaluate( int gridU, int gridV, float *B, vec3 patch[][4] );
+ vec3 evaluateNormal( int gridU, int gridV, float *B, float *dB, vec3 patch[][4] );
+ void moveLid(int,float *,mat4);
+
+public:
+ VBOTeapot(int grid, mat4 lidTransform);
+
+
+ // Inherited via ADrawable
+ virtual void draw(ShaderProgram * shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) override;
+
+ virtual DrawableType getType() override;
+
+};
+
+#endif // VBOTEAPOT_H