Files
rez_demo/GL_STUFF/SOURCES/SCENE/Model3D.cpp

160 lines
4.7 KiB
C++
Raw Normal View History

#include "../../HEADERS/SCENE/Model3D.hpp"
extern "C" {
#include "../../GLES_3_1_compatibility.h"
}
#include "../../HEADERS/UTILS/OnlyOnce.hpp"
#include "../../HEADERS/UTILS/ShaderMaker.h"
#include "../../HEADERS/SCENE/objloader.hpp"
#include "../../HEADERS/UTILS/ResourceCache.h"
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
/* the gl**OES functions are calls which are not in the original OpenGL ES 2
OpenGL ES 3 would have supported them, ES 2 offers them as extensions
*/
Model3D::Model3D(const char* modelPath, bool smoothNormals) {
vector<vec3> points = loadVertexData(modelPath, smoothNormals);
computeBoundingBox(points);
}
void Model3D::computeBoundingBox(vector<vec3> points) {
boundingBoxLBN = points[0];
boundingBoxRTF = points[0];
for (const vec3& point : points) {
boundingBoxLBN.x = glm::min(boundingBoxLBN.x, point.x);
boundingBoxLBN.y = glm::min(boundingBoxLBN.y, point.y);
boundingBoxLBN.z = glm::max(boundingBoxLBN.z, point.z);
boundingBoxRTF.x = glm::max(boundingBoxRTF.x, point.x);
boundingBoxRTF.y = glm::max(boundingBoxRTF.y, point.y);
boundingBoxRTF.z = glm::min(boundingBoxRTF.z, point.z);
}
}
vector<vec3> Model3D::loadVertexData(const char* modelPath, bool smoothNormals) {
unsigned int vbo, vboUv, vboNor, vboTangent, vboBitangent;
vector<vec3> vertices;
vector<int> verticesIndex;
vector<vec2> verticesUv;
vector<vec3> verticesNor;
vector<vec3> verticesTangent;
vector<vec3> verticesBitangent;
loadOBJ(modelPath, vertices, verticesUv, verticesNor, smoothNormals);
/* the windows version was happy even with %d */
printf("Vertici : %ld\tUVcoord : %ld\tNormali : %ld\n", vertices.size(), verticesUv.size(), verticesNor.size() );
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// VBO vertici
{
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vec3), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0/* 3 * sizeof(float)*/, 0);
Model3D::nVertices = vertices.size();
}
// VBO coordinate UV
{
glGenBuffers(1, &vboUv);
glBindBuffer(GL_ARRAY_BUFFER, vboUv);
glBufferData(GL_ARRAY_BUFFER, verticesUv.size() * sizeof(vec2), &verticesUv[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,0 /*2 * sizeof(float)*/, 0);
}
// VBO normali
{
glGenBuffers(1, &vboNor);
glBindBuffer(GL_ARRAY_BUFFER, vboNor);
glBufferData(GL_ARRAY_BUFFER, verticesNor.size() * sizeof(vec3), &verticesNor[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0/* 3 * sizeof(float)*/,0);
}
// VBO tangenti e VBO bitangenti
{
for (int i = 0; i < vertices.size(); i += 3) {
//erano del tipo vec2& =
// Shortcuts for vertices
vec3 v0 = vertices[i + 0];
vec3 v1 = vertices[i + 1];
vec3 v2 = vertices[i + 2];
// Shortcuts for UVs
vec2 uv0 = verticesUv[i + 0];
vec2 uv1 = verticesUv[i + 1];
vec2 uv2 = verticesUv[i + 2];
// Edges of the triangle : position delta
vec3 deltaPos1 = v1 - v0;
vec3 deltaPos2 = v2 - v0;
// UV delta
vec2 deltaUV1 = uv1 - uv0;
vec2 deltaUV2 = uv2 - uv0;
float r = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x);
vec3 tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y) * r;
vec3 bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x) * r;
// Set the same tangent for all three vertices of the triangle.
verticesTangent.push_back(tangent);
verticesTangent.push_back(tangent);
verticesTangent.push_back(tangent);
// Same thing for bitangents
verticesBitangent.push_back(bitangent);
verticesBitangent.push_back(bitangent);
verticesBitangent.push_back(bitangent);
}
glGenBuffers(1, &vboTangent);
glBindBuffer(GL_ARRAY_BUFFER, vboTangent);
glBufferData(GL_ARRAY_BUFFER, verticesTangent.size() * sizeof(vec3), &verticesTangent[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0);
glGenBuffers(1, &vboBitangent);
glBindBuffer(GL_ARRAY_BUFFER, vboBitangent);
glBufferData(GL_ARRAY_BUFFER, verticesBitangent.size() * sizeof(vec3), &verticesBitangent[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 0, 0);
}
return vertices;
}
void Model3D::draw() {
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, nVertices);
glBindVertexArray(0);
}
GLuint Model3D::getVAO() {
return this->vao;
}
int Model3D::getTrisCount() {
return this->nVertices;
}
vec3 Model3D::getLBN() {
return boundingBoxLBN;
}
vec3 Model3D::getRTF() {
return boundingBoxRTF;
}