This commit is contained in:
RochesterX
2026-01-07 14:06:26 -05:00
commit 8b181b34e6
40 changed files with 2014836 additions and 0 deletions

432
include/object.hpp Normal file
View File

@@ -0,0 +1,432 @@
#ifndef OBJECT_H
#define OBJECT_H
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <shader.hpp>
#include <texture.hpp>
#include <vector>
using std::vector;
using glm::vec3;
using glm::mat4;
typedef struct
{
vec3 position;
vec3 color;
vec3 normal;
} Vertex;
class Object
{
public:
const char* path;
vec3 position;
vec3 rotation;
vec3 scale;
vector<float> vertexData;
vector<Vertex> vertices;
vector<vec3> normals;
vector<unsigned int> indices;
vector<unsigned int> normalIndices;
unsigned int VAO;
unsigned int VBO;
unsigned int EBO;
Texture texture1;
Object()
{
}
Object(const vec3 p, const vec3 r, const vec3 s, const char* objFilePath)
{
this->position = p;
this->rotation = r;
this->scale = s;
this->path = objFilePath;
std::string obj;
std::ifstream objFile;
std::stringstream objStringStream;
objFile.exceptions(std::ifstream::failbit | std:: ifstream::badbit);
try
{
objFile.open(objFilePath);
objStringStream << objFile.rdbuf();
objFile.close();
obj = objStringStream.str();
}
catch (std::ifstream::failure e)
{
std::cout << "Error reading obj file.";
}
std::string line;
while (std::getline(objStringStream, line))
{
//std::cout << "\n\nLINE: " << line << std::endl;
std::istringstream lineStream(line);
std::string lineType;
lineStream >> lineType;
//std::cout << lineType << std::endl;
//std::cout << "Reading line of type " << lineType << std::endl;
if (lineType == "v")
{
Vertex vertex;
std::string token;
float vector[3];
for (int i = 0 ; i < 6; i++)
{
//std::cout << "I VALUE: " << i << std::endl;
float value = 1;
if (!(lineStream >> token))
{
vector[i % 3] = 1;
//std::cout << "Adding 1 to vertexData because nothing else." << std::endl;
}
else
{
vector[i % 3] = std::stof(token);
//std::cout << "Adding " << token << " to vertexData." << std::endl;
}
if (i == 2)
{
vertex.position = vec3(vector[0], vector[1], vector[2]);
//std::cout << " BEGIN POSITION" << std::endl <<vector[0] << " ";
//std::cout << vector[1] << " ";
//std::cout << vector[2] << " " << std::endl;
}
else if (i == 5)
{
vertex.color = vec3(vector[0], vector[1], vector[2]);
//std::cout << " BEGIN COLOR" << std::endl <<vector[0] << " ";
//std::cout << vector[1] << " ";
//std::cout << vector[2] << " " << std::endl;
}
}
vertices.push_back(vertex);
}
else if (lineType == "vn")
{
vec3 normal;
std::string token;
float vector[3];
for (int i = 0 ; i < 3; i++)
{
//std::cout << "I VALUE: " << i << std::endl;
float value = 1;
if (!(lineStream >> token))
{
vector[i % 3] = 1;
//std::cout << "Adding 1 to vertexData because nothing else." << std::endl;
}
else
{
vector[i % 3] = std::stof(token);
//std::cout << "Adding " << token << " to vertexData." << std::endl;
}
if (i == 2)
{
normal = vec3(vector[0], vector[1], vector[2]);
//std::cout << " BEGIN POSITION" << std::endl <<vector[0] << " ";
//std::cout << vector[1] << " ";
//std::cout << vector[2] << " " << std::endl;
}
}
normals.push_back(normal);
}
else if (lineType == "f")
{
std::string token;
std::vector<unsigned int> tokenIndices;
std::vector<unsigned int> tokenTexCoords;
std::vector<unsigned int> tokenNormals;
for (int i = 0; lineStream >> token; i++)
{
std::istringstream tokenStream(token);
std::string element;
int index, texCoord, normal;
for (int i = 0; std::getline(tokenStream, element, '/'); i++)
{
//std::cout << "element is " << element << std::endl;
switch (i)
{
// Vertex index
case 0:
index = std::stoi(token);
tokenIndices.push_back(index);
break;
// Vertex texture coordinates
case 1:
texCoord = std::stoi(token);
tokenTexCoords.push_back(texCoord);
break;
// Vertex normal
case 2:
if (normals.size() == 0) break;
normal = std::stoi(token);
tokenNormals.push_back(normal);
break;
}
}
}
// Iterate through each index (X/0/0) in the f line
for (int i = 1; i < tokenIndices.size() - 1; i++)
{
//std::cout << "token index " << i << std::endl;
// Create triangle (0, i, i + 1)
for (int which = 0; which < 3; which++)
{
int index;
switch (which)
{
case 0:
index = 0;
break;
case 1:
index = i;
break;
case 2:
index = i + 1;
break;
}
if (index >= 0)
{
//std::cout << "pushing " <<tokenIndices[index] - 1 << " to indices" << std::endl;
indices.push_back(tokenIndices[index] - 1);
if (tokenNormals.size() > index) normalIndices.push_back(tokenNormals[index] - 1);
//if (tokenNormals.size() == tokenIndices.size())
//{
// normals.push_back(tokenNormals[index - 1]);
//}
//std::cout << "Pushed " << index - 1 << " to indices" << std::endl;
continue;
}
// Negative index
indices.push_back((vertices.size()) + tokenIndices[index]);
if (tokenNormals.size() > index) normalIndices.push_back((normals.size()) + tokenNormals[index]);
//if (tokenNormals.size() == tokenIndices.size())
//{
// normals.push_back((vertexData.size() / 6) + tokenNormals[index]);
//}
//std::cout << "Pushed " << vertexData.size() + index << " to indices" << std::endl;
}
}
}
}
std::cout << path << ": Indices: " << indices.size() << "; Normals: " << normalIndices.size() << std::endl;
/*for (vec3 normal : normals)
{
std::cout << normal.x << " " << normal.y << " " << normal.z << std::endl;
}
*/std::cout << std::endl;
// Loop through indices and insert normals to vertices
for (int i = 0; i < indices.size(); i++)
{
if (indices.size() != normalIndices.size())
{
std::cout << "WARNING: Inequal number of vertex indices and normal indices. Skipping normals." << std::endl;
break;
}
vertices[indices[i]].normal = normals[normalIndices[i]];
}
// Generate vertexData
for (int i = 0; i < vertices.size(); i++)
{
Vertex vertex = vertices[i];
vertexData.push_back(vertex.position.x);
vertexData.push_back(vertex.position.y);
vertexData.push_back(vertex.position.z);
vertexData.push_back(vertex.color.x);
vertexData.push_back(vertex.color.y);
vertexData.push_back(vertex.color.z);
vertexData.push_back(vertex.normal.x);
vertexData.push_back(vertex.normal.y);
vertexData.push_back(vertex.normal.z);
//std::cout << vertex.position.x << " ";
//std::cout << vertex.position.y << " ";
//std::cout << vertex.position.z << "\t\t\t";
//std::cout << vertex.color.x << " ";
//std::cout << vertex.color.y << " ";
//std::cout << vertex.color.z << std::endl;
}
//std::cout << "Length of vertices: " << vertices.size() << std::endl;
//std::cout << "Path of this one " << path << std::endl << std::endl;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(float), &vertexData[0], GL_STATIC_DRAW);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
}
/*
Object(const vec3 p, const vec3 r, const vec3 s, vector<float> v, vector<unsigned int> i, Texture t1 = nullptr)
{
this->position = p;
this->rotation = r;
this->scale = s;
this->vertexData = v;
this->indices = i;
this->texture1 = t1;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(float), &vertexData[0], GL_STATIC_DRAW);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
}
*/
void draw(Shader s)
{
/*mat4 mod = rotationMatrix();
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
std::cout << mod[i][j] << "\t";
}
std::cout << std::endl;
}*/
s.setMat4("modelMatrix", &modelMatrix()[0][0]);
s.setMat4("normalMatrix", &normalMatrix()[0][0]);
texture1.activate(0);
s.use();
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
s.setInt("texture1", 0);
s.setVec3("lightColor", 1.0, 1.0, 1.0);
s.setVec3("objectColor", 0.8, 0.4, 0.2);
s.setVec3("lightPos", sin(glfwGetTime() / 3.0f) * 10, 8.0, cos(glfwGetTime() / 3.0f) * 10);
glBindVertexArray(0);
}
mat4 translationMatrix()
{
return mat4(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
position.x, position.y, position.z, 1
);
}
mat4 rotationMatrix()
{
mat4 x(
1, 0, 0, 0,
0, cos(rotation.x), sin(rotation.x), 0,
0, -sin(rotation.x), cos(rotation.x), 0,
0, 0, 0, 1
);
mat4 y(
cos(rotation.y), 0, -sin(rotation.y), 0,
0, 1, 0, 0,
sin(rotation.y), 0, cos(rotation.y), 0,
0, 0, 0, 1
);
mat4 z(
cos(rotation.z), sin(rotation.z), 0, 0,
-sin(rotation.z), cos(rotation.z), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
return z * y * x;
}
mat4 scaleMatrix()
{
return mat4(
scale.x, 0, 0, 0,
0, scale.y, 0, 0,
0, 0, scale.z, 0,
0, 0, 0, 1
);
}
mat4 modelMatrix()
{
return translationMatrix() * rotationMatrix() * scaleMatrix();
}
mat4 normalMatrix()
{
return glm::transpose(glm::inverse(modelMatrix()));
}
};
#endif