obj loader
This commit is contained in:
36
inc/engine/obj_loader.hpp
Normal file
36
inc/engine/obj_loader.hpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef OBJ_LOADER_HPP
|
||||||
|
#define OBJ_LOADER_HPP
|
||||||
|
|
||||||
|
// Includes
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
// OBJLoader class definition
|
||||||
|
class OBJLoader {
|
||||||
|
public:
|
||||||
|
// Vertex structure
|
||||||
|
typedef struct {
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec3 normal;
|
||||||
|
glm::vec2 texCoord;
|
||||||
|
} Vertex;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
OBJLoader(std::string filepath);
|
||||||
|
|
||||||
|
// convert loaded data to arrays
|
||||||
|
float *getVertexData();
|
||||||
|
unsigned int *getIndexData();
|
||||||
|
size_t getVertexCount();
|
||||||
|
size_t getIndexCount();
|
||||||
|
bool isLoaded() const { return loaded; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string filepath;
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
std::vector<unsigned int> indices;
|
||||||
|
bool loaded = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
layout(location = 0) in vec3 position; // Vertex position
|
layout(location = 0) in vec3 position; // Vertex position
|
||||||
layout(location = 1) in vec3 inColor; // Vertex color
|
layout(location = 1) in vec3 normal; // Vertex normal
|
||||||
|
layout(location = 2) in vec2 texCoord; // Vertex texture coordinate
|
||||||
out vec3 color; // Output color to the fragment shader
|
out vec3 color; // Output color to the fragment shader
|
||||||
|
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
@@ -10,5 +11,5 @@ uniform mat4 projection;
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = projection * view * model * vec4(position, 1.0); // Apply transformation matrices
|
gl_Position = projection * view * model * vec4(position, 1.0); // Apply transformation matrices
|
||||||
color = inColor; // Set the color output
|
color = vec3(1.0, 0.5, 0.2); // Set output color (orange)
|
||||||
}
|
}
|
||||||
84
src/engine/obj_loader.cpp
Normal file
84
src/engine/obj_loader.cpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#include "engine/obj_loader.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
OBJLoader::OBJLoader(std::string filepath) : filepath(filepath), loaded(true) {
|
||||||
|
std::ifstream file(filepath);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
loaded = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<glm::vec3> temp_positions;
|
||||||
|
std::vector<glm::vec3> temp_normals;
|
||||||
|
std::vector<glm::vec2> temp_texCoords;
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(file, line)) {
|
||||||
|
std::istringstream ss(line);
|
||||||
|
std::string prefix;
|
||||||
|
ss >> prefix;
|
||||||
|
|
||||||
|
if (prefix == "v") {
|
||||||
|
glm::vec3 position;
|
||||||
|
ss >> position.x >> position.y >> position.z;
|
||||||
|
temp_positions.push_back(position);
|
||||||
|
} else if (prefix == "vn") {
|
||||||
|
glm::vec3 normal;
|
||||||
|
ss >> normal.x >> normal.y >> normal.z;
|
||||||
|
temp_normals.push_back(normal);
|
||||||
|
} else if (prefix == "vt") {
|
||||||
|
glm::vec2 texCoord;
|
||||||
|
ss >> texCoord.x >> texCoord.y;
|
||||||
|
temp_texCoords.push_back(texCoord);
|
||||||
|
} else if (prefix == "f") {
|
||||||
|
unsigned int posIdx[3], texIdx[3], normIdx[3];
|
||||||
|
char slash; // to consume the '/' characters
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
ss >> posIdx[i] >> slash >> texIdx[i] >> slash >> normIdx[i];
|
||||||
|
Vertex vertex;
|
||||||
|
vertex.position = temp_positions[posIdx[i] - 1];
|
||||||
|
vertex.texCoord = temp_texCoords[texIdx[i] - 1];
|
||||||
|
vertex.normal = temp_normals[normIdx[i] - 1];
|
||||||
|
vertices.push_back(vertex);
|
||||||
|
indices.push_back(static_cast<unsigned int>(vertices.size() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert loaded vertex data to a contiguous float array
|
||||||
|
float* OBJLoader::getVertexData() {
|
||||||
|
size_t vertexCount = vertices.size();
|
||||||
|
float* vertexData = new float[vertexCount * 8]; // 3 pos + 3 normal + 2 texCoord
|
||||||
|
for (size_t i = 0; i < vertexCount; ++i) {
|
||||||
|
vertexData[i * 8 + 0] = vertices[i].position.x;
|
||||||
|
vertexData[i * 8 + 1] = vertices[i].position.y;
|
||||||
|
vertexData[i * 8 + 2] = vertices[i].position.z;
|
||||||
|
vertexData[i * 8 + 3] = vertices[i].normal.x;
|
||||||
|
vertexData[i * 8 + 4] = vertices[i].normal.y;
|
||||||
|
vertexData[i * 8 + 5] = vertices[i].normal.z;
|
||||||
|
vertexData[i * 8 + 6] = vertices[i].texCoord.x;
|
||||||
|
vertexData[i * 8 + 7] = vertices[i].texCoord.y;
|
||||||
|
}
|
||||||
|
return vertexData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert loaded index data to a contiguous unsigned int array
|
||||||
|
unsigned int* OBJLoader::getIndexData() {
|
||||||
|
size_t indexCount = indices.size();
|
||||||
|
unsigned int* indexData = new unsigned int[indexCount];
|
||||||
|
for (size_t i = 0; i < indexCount; ++i) {
|
||||||
|
indexData[i] = indices[i];
|
||||||
|
}
|
||||||
|
return indexData;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t OBJLoader::getVertexCount() {
|
||||||
|
return vertices.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t OBJLoader::getIndexCount() {
|
||||||
|
return indices.size();
|
||||||
|
}
|
||||||
41
src/main.cpp
41
src/main.cpp
@@ -1,10 +1,6 @@
|
|||||||
#define GL_GLEXT_PROTOTYPES
|
|
||||||
#include "engine/sdl.hpp"
|
#include "engine/sdl.hpp"
|
||||||
#include "engine/opengl.hpp"
|
#include "engine/opengl.hpp"
|
||||||
|
#include "engine/obj_loader.hpp"
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
SDLWindow window("My SDL Application", 800, 600);
|
SDLWindow window("My SDL Application", 800, 600);
|
||||||
@@ -12,9 +8,8 @@ int main(int argc, char* argv[]) {
|
|||||||
OpenGLContext glContext(window);
|
OpenGLContext glContext(window);
|
||||||
if (!glContext.isInitialized()) { return -1; }
|
if (!glContext.isInitialized()) { return -1; }
|
||||||
|
|
||||||
|
|
||||||
Camera camera(
|
Camera camera(
|
||||||
glm::vec3(0.0f, 0.0f, 3.0f), // Position
|
glm::vec3(2.0f, 1.0f, 3.0f), // Position
|
||||||
glm::vec3(0.0f, 0.0f, 0.0f), // Target
|
glm::vec3(0.0f, 0.0f, 0.0f), // Target
|
||||||
glm::vec3(0.0f, 1.0f, 0.0f) // Up vector
|
glm::vec3(0.0f, 1.0f, 0.0f) // Up vector
|
||||||
);
|
);
|
||||||
@@ -28,29 +23,25 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
Shader shader_program("shaders/triangle.vert", "shaders/triangle.frag");
|
Shader shader_program("shaders/triangle.vert", "shaders/triangle.frag");
|
||||||
|
|
||||||
// vertex, color
|
OBJLoader objLoader("assets/models/suzanne.obj");
|
||||||
float vertexData[] = {
|
if (!objLoader.isLoaded()) {
|
||||||
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // top right
|
SDL_Log("Failed to load OBJ model.");
|
||||||
0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom right
|
return -1;
|
||||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // top left
|
}
|
||||||
-0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f // bottom left
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned int indexData[] = {
|
|
||||||
0, 1, 2, // first triangle
|
|
||||||
1, 3, 2 // second triangle
|
|
||||||
};
|
|
||||||
|
|
||||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
||||||
|
|
||||||
VertexArrayObject VAO;
|
VertexArrayObject VAO;
|
||||||
VAO.bufferVertexData(vertexData, sizeof(vertexData));
|
VAO.bufferVertexData(objLoader.getVertexData(), objLoader.getVertexCount() * sizeof(float) * 8);
|
||||||
VAO.bufferElementData(indexData, sizeof(indexData));
|
VAO.bufferElementData(objLoader.getIndexData(), objLoader.getIndexCount() * sizeof(unsigned int));
|
||||||
VAO.setAttributePointer(0, 3, GL_FLOAT, false, 6 * sizeof(float), 0); // position
|
VAO.setAttributePointer(0, 3, GL_FLOAT, false, 8 * sizeof(float), 0); // position
|
||||||
VAO.setAttributePointer(1, 3, GL_FLOAT, false, 6 * sizeof(float), 3 * sizeof(float)); // color
|
VAO.setAttributePointer(1, 3, GL_FLOAT, false, 8 * sizeof(float), 3 * sizeof(float)); // normal
|
||||||
|
VAO.setAttributePointer(2, 2, GL_FLOAT, false, 8 * sizeof(float), 6 * sizeof(float)); // texCoord
|
||||||
|
|
||||||
|
// Wireframe mode
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
|
||||||
window.setPosition(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
window.setPosition(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||||
window.showWindow();
|
window.showWindow();
|
||||||
|
|
||||||
while (window.isRunning()) {
|
while (window.isRunning()) {
|
||||||
window.pollEvents();
|
window.pollEvents();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user