198 lines
6.8 KiB
C++
198 lines
6.8 KiB
C++
#include "phongentity.h"
|
|
#include "shader.h"
|
|
#include <glm/glm.hpp>
|
|
#include "phongmaterial.h"
|
|
#include "mesh.h"
|
|
#include <glm/ext.hpp>
|
|
#include "glassert.h"
|
|
#include "sparrowrenderer.h"
|
|
|
|
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
|
|
|
PhongEntity::PhongEntity(Mesh* myMesh) :
|
|
mesh(myMesh),
|
|
vao(0),
|
|
nb_buffers(0),
|
|
vbo(NULL),
|
|
displayList(0),
|
|
modelMatrix()
|
|
{}
|
|
|
|
void PhongEntity::draw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights)
|
|
{
|
|
if(SparrowRenderer::isModernOpenGLAvailable())
|
|
modernDraw(viewMatrix, projectionMatrix, dirLight, pointLights);
|
|
else
|
|
crappyDraw(viewMatrix, projectionMatrix, dirLight, pointLights);
|
|
}
|
|
|
|
void PhongEntity::modernDraw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights)
|
|
{
|
|
glm::mat4 modelViewMatrix = viewMatrix * modelMatrix;
|
|
glm::mat4 mvp = projectionMatrix * modelViewMatrix;
|
|
glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix));
|
|
for(int i=0; i<mesh->indiceGroups.size(); ++i)
|
|
{
|
|
PhongMaterial* mat = (PhongMaterial*)mesh->indiceGroups[i].material;
|
|
mat->bindAttributes();
|
|
Shader* shader = mat->getShader();
|
|
shader->bindMatrix(shader->getLocation("viewMatrix"), viewMatrix);
|
|
shader->bindMatrix(shader->getLocation("modelViewMatrix"), modelViewMatrix);
|
|
shader->bindMatrix(shader->getLocation("normalMatrix"), normalMatrix);
|
|
shader->bindMatrix(shader->getLocation("MVP"), mvp);
|
|
shader->bindVec3Array(shader->getLocation("dirLight"), (glm::vec3*)dirLight, 2);
|
|
pointLights->bind(shader->getLocation("pointLights"), shader->getLocation("nbPointLights"), shader);
|
|
drawGroup(i);
|
|
}
|
|
}
|
|
|
|
void PhongEntity::crappyDraw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights)
|
|
{
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glm::mat4 modelViewMatrix = viewMatrix * modelMatrix;
|
|
glLoadMatrixf(glm::value_ptr(modelViewMatrix));
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadMatrixf(glm::value_ptr(projectionMatrix));
|
|
glCallList(displayList);
|
|
}
|
|
|
|
void PhongEntity::modernInit(bool isDynamic)
|
|
{
|
|
GLenum buffer_type = isDynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
|
|
|
|
// create VAO
|
|
glAssert(glGenVertexArrays(1, &vao));
|
|
glAssert(glBindVertexArray(vao));
|
|
|
|
nb_buffers = 1; // positions buffer
|
|
if(mesh->hasNormals())
|
|
++nb_buffers;
|
|
if(mesh->hasTexCoords())
|
|
++nb_buffers;
|
|
if(mesh->hasTangents())
|
|
++nb_buffers;
|
|
|
|
nb_buffers += mesh->indiceGroups.size();
|
|
|
|
// create VBOs
|
|
vbo = new GLuint[nb_buffers]();
|
|
glAssert(glGenBuffers(nb_buffers, vbo));
|
|
|
|
for(const Mesh::Group &g : mesh->indiceGroups)
|
|
{
|
|
// init indices vbos
|
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[INDICES_BUFFER]));
|
|
glAssert(glBufferData(GL_ARRAY_BUFFER, g.indices.size() * sizeof(GLuint), g.indices.data(), buffer_type));
|
|
}
|
|
|
|
// init positions vbo
|
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[POSITION_BUFFER]));
|
|
glAssert(glBufferData(GL_ARRAY_BUFFER, mesh->positions.size() * sizeof(glm::vec3), mesh->positions.data(), buffer_type));
|
|
|
|
if(mesh->hasNormals())
|
|
{
|
|
// init normals vbo
|
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]));
|
|
glAssert(glBufferData(GL_ARRAY_BUFFER, mesh->normals.size() * sizeof(glm::vec3), mesh->normals.data(), buffer_type));
|
|
}
|
|
|
|
if(mesh->hasNormals())
|
|
{
|
|
// init texCoords vbo
|
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]));
|
|
glAssert(glBufferData(GL_ARRAY_BUFFER, mesh->texCoords.size() * sizeof(glm::vec2), mesh->texCoords.data(), buffer_type));
|
|
}
|
|
|
|
if(mesh->hasTangents())
|
|
{
|
|
// init tangents vbo
|
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER]));
|
|
glAssert(glBufferData(GL_ARRAY_BUFFER, mesh->tangents.size() * sizeof(glm::vec3)*2, mesh->tangents.data(), buffer_type));
|
|
}
|
|
|
|
// unbind vao
|
|
glAssert(glBindVertexArray(0));
|
|
}
|
|
|
|
void PhongEntity::crappyInit()
|
|
{
|
|
displayList = glAssert(glGenLists(1));
|
|
glAssert(glNewList(displayList, GL_COMPILE));
|
|
for(int i=0; i<mesh->indiceGroups.size(); ++i)
|
|
{
|
|
PhongMaterial* mat = (PhongMaterial*)(mesh->indiceGroups[i].material);
|
|
mat->bindAttributes();
|
|
glAssert(glBegin(GL_TRIANGLES));
|
|
for(int j=0; j<mesh->indiceGroups[i].indices.size(); ++j)
|
|
{
|
|
int vid = mesh->indiceGroups[i].indices[j];
|
|
glNormal3fv(glm::value_ptr(mesh->normals[vid]));
|
|
glTexCoord2fv(glm::value_ptr(mesh->texCoords[vid]));
|
|
glVertex3fv(glm::value_ptr(mesh->positions[vid]));
|
|
}
|
|
glAssert(glEnd());
|
|
}
|
|
glAssert(glEndList());
|
|
}
|
|
|
|
void PhongEntity::initGL(bool isDynamic)
|
|
{
|
|
if(SparrowRenderer::isModernOpenGLAvailable())
|
|
modernInit(isDynamic);
|
|
else
|
|
crappyInit();
|
|
}
|
|
|
|
void PhongEntity::destroyGL()
|
|
{
|
|
if(SparrowRenderer::isModernOpenGLAvailable())
|
|
{
|
|
glAssert(glDeleteVertexArrays(1, &vao));
|
|
glAssert(glDeleteBuffers(nb_buffers, vbo));
|
|
delete[] vbo;
|
|
vbo = NULL;
|
|
}
|
|
else
|
|
glAssert(glDeleteLists(displayList, 1));
|
|
}
|
|
|
|
void PhongEntity::drawGroup(int groupId)
|
|
{
|
|
glAssert(glBindVertexArray(vao));
|
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[POSITION_BUFFER]));
|
|
glAssert(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
|
|
glAssert(glEnableVertexAttribArray(0));
|
|
if(mesh->hasNormals())
|
|
{
|
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]));
|
|
glAssert(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
|
|
glAssert(glEnableVertexAttribArray(1));
|
|
}
|
|
if(mesh->hasTexCoords())
|
|
{
|
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]));
|
|
glAssert(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), BUFFER_OFFSET(0)));
|
|
glAssert(glEnableVertexAttribArray(2));
|
|
}
|
|
if(mesh->hasTangents())
|
|
{
|
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER]));
|
|
glAssert(glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Mesh::Tangents), BUFFER_OFFSET(0)));
|
|
glAssert(glEnableVertexAttribArray(3));
|
|
glAssert(glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Mesh::Tangents), BUFFER_OFFSET(sizeof(glm::vec3))));
|
|
glAssert(glEnableVertexAttribArray(4));
|
|
}
|
|
glAssert(glDrawElements(GL_TRIANGLES, mesh->indiceGroups[groupId].indices.size(), GL_UNSIGNED_INT, mesh->indiceGroups[groupId].indices.data()));
|
|
}
|
|
|
|
PhongEntity* PhongEntity::clone()
|
|
{
|
|
PhongEntity* myClone = new PhongEntity(mesh);
|
|
myClone->modelMatrix = modelMatrix;
|
|
myClone->displayList = displayList;
|
|
myClone->nb_buffers = nb_buffers;
|
|
myClone->vao = vao;
|
|
myClone->vbo = vbo;
|
|
return myClone;
|
|
}
|