Scene with 3 illuminated models : cube sphere teapot

This commit is contained in:
Hugo Willaume 2018-11-28 10:23:34 +09:00
parent 7e546f7d23
commit 9e895bbcfd
23 changed files with 1012 additions and 130 deletions

View File

@ -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

View File

@ -157,6 +157,8 @@
<ClCompile Include="LineSegment.cpp" />
<ClCompile Include="MyGLWindow.cpp" />
<ClCompile Include="Source.cpp" />
<ClCompile Include="Sphere.cpp" />
<ClCompile Include="vboteapot.cpp" />
<ClCompile Include="Viewer.cpp" />
<ClCompile Include="WireCube.cpp" />
</ItemGroup>
@ -177,11 +179,14 @@
<ClInclude Include="Loader.h" />
<ClInclude Include="ModelView.h" />
<ClInclude Include="MyGLWindow.h" />
<ClInclude Include="Sphere.h" />
<ClInclude Include="teapotdata.h" />
<ClInclude Include="vboteapot.h" />
<ClInclude Include="Viewer.h" />
<ClInclude Include="WireCube.h" />
</ItemGroup>
<ItemGroup>
<None Include="simple.vert">
<None Include="light.vert">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Geometry</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Geometry</ShaderType>
@ -192,6 +197,7 @@
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4.0</ShaderModel>
<FileType>Document</FileType>
</None>
<None Include="simple.vert" />
</ItemGroup>
<ItemGroup>
<None Include="simple.frag" />

View File

@ -60,6 +60,12 @@
<ClCompile Include="LineSegment.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Sphere.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="vboteapot.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ColorCube.h">
@ -116,11 +122,23 @@
<ClInclude Include="LineSegment.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Sphere.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="teapotdata.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="vboteapot.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="simple.frag">
<Filter>Shaders</Filter>
</None>
<None Include="light.vert">
<Filter>Shaders</Filter>
</None>
<None Include="simple.vert">
<Filter>Shaders</Filter>
</None>

View File

@ -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();

View File

@ -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;
};

View File

@ -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<glm::vec3> 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<GLfloat> 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<glm::vec3> 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();
}

View File

@ -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();
};

View File

@ -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;
};

View File

@ -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);

View File

@ -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();

View File

@ -1,6 +1,6 @@
#include <algorithm>
#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<glm::mat4x4>()));
_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)

View File

@ -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<std::string, float> 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<ADrawable *> _static_drawables;
std::vector<ADrawable *> _crane_boom;
std::vector<ADrawable *> _light_drawables;
void setup();
void setViewFromBox(glm::vec3 &eye, glm::vec3 &look, glm::vec3 &up);

View File

@ -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();

191
BaseGLProject/Sphere.cpp Normal file
View File

@ -0,0 +1,191 @@
#include "Sphere.h"
#include <glm//gtc/constants.hpp>
#include <glm/vec3.hpp>
#include <glm/mat3x3.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/matrix_inverse.hpp>
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<float>() / slices;
GLfloat phiFac = glm::pi<float>() / 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;
}

45
BaseGLProject/Sphere.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef ___SPHERE_H
#define ___SPHERE_H
#include "GL/glew.h"
#include <GL/GL.h>
#include <glm/mat4x4.hpp>
#include <vector>
#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

View File

@ -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);

View File

@ -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();

View File

@ -45,6 +45,6 @@ Collapsed=0
[Window][First Window]
Pos=20,20
Size=350,150
Size=322,75
Collapsed=0

42
BaseGLProject/light.vert Normal file
View File

@ -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);
}

View File

@ -11,4 +11,4 @@ void main(void)
{
f_color = v_color;
gl_Position = mvp * vec4(coord3d, 1.0f);
}
}

206
BaseGLProject/teapotdata.h Normal file
View File

@ -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

326
BaseGLProject/vboteapot.cpp Normal file
View File

@ -0,0 +1,326 @@
#include "vboteapot.h"
#include "teapotdata.h"
#include <GL/glew.h>
#include <GL/gl.h>
#include <cstdio>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/matrix_inverse.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/constants.hpp>
//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 ) );
}

52
BaseGLProject/vboteapot.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef VBOTEAPOT_H
#define VBOTEAPOT_H
#include <GL/glew.h>
#include <GL/gl.h>
#include <glm/glm.hpp>
#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