#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 #include /* 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 points = loadVertexData(modelPath, smoothNormals); computeBoundingBox(points); } void Model3D::computeBoundingBox(vector 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 Model3D::loadVertexData(const char* modelPath, bool smoothNormals) { unsigned int vbo, vboUv, vboNor, vboTangent, vboBitangent; vector vertices; vector verticesIndex; vector verticesUv; vector verticesNor; vector verticesTangent; vector 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; }