192 lines
4.5 KiB
C++
192 lines
4.5 KiB
C++
#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;
|
|
}
|
|
|