-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathModelLoader.cpp
More file actions
151 lines (121 loc) · 4.63 KB
/
Copy pathModelLoader.cpp
File metadata and controls
151 lines (121 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "ModelLoader.h"
#include <fstream>
#include <sstream>
#include <iostream>
ModelLoader::ModelLoader(const std::string& objFilename, const std::string& textureFilename)
: textureID(0) { // Initialize textureID to 0
if (!loadObj(objFilename)) {
std::cerr << "Failed to load OBJ file: " << objFilename << std::endl;
}
if (!loadTexture(textureFilename)) {
std::cerr << "Failed to load texture file: " << textureFilename << std::endl;
}
}
ModelLoader::~ModelLoader() {
glDeleteTextures(1, &textureID);
}
void ModelLoader::render() {
if (textureID == 0) {
return;
}
GLfloat color[4] = { 1.0, 1.0, 1.0 , 1.0 };
glColor4fv(color);
GLfloat specular[] = { 1.0f, 1.0f, 1.0f },
shininess = 128.0f;
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialf(GL_FRONT, GL_SHININESS, shininess);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
glTranslatef(0, 2.7, 0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureID);
glBegin(GL_TRIANGLES);
for (const Face& face : faces) {
for (int i = 0; i < 3; ++i) {
const TexCoord& texCoord = texCoords[face.texCoordIndex[i]];
const Vertex& vertex = vertices[face.vertexIndex[i]];
glTexCoord2f(texCoord.u, texCoord.v);
glVertex3f(vertex.x, vertex.y, vertex.z);
}
}
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
}
bool ModelLoader::loadObj(const std::string& filename) {
std::ifstream objFile(filename);
if (!objFile.is_open()) {
return false;
}
std::string line;
while (std::getline(objFile, line)) {
std::istringstream lineStream(line);
std::string type;
lineStream >> type;
if (type == "v") {
Vertex vertex;
lineStream >> vertex.x >> vertex.y >> vertex.z;
vertices.push_back(vertex);
}
else if (type == "vt") {
TexCoord texCoord;
lineStream >> texCoord.u >> texCoord.v;
texCoords.push_back(texCoord);
}
else if (type == "f") {
Face face;
char slash;
int normalIndex; // Add a variable to store the normal index
for (int i = 0; i < 3; ++i) {
// Add another slash to the input stream extraction to handle the normal index
lineStream >> face.vertexIndex[i] >> slash >> face.texCoordIndex[i] >> slash >> normalIndex;
// Adjust indices to be zero-based
--face.vertexIndex[i];
--face.texCoordIndex[i];
// ... (the rest of the function remains unchanged)
}
faces.push_back(face);
}
}
objFile.close();
return true;
}
bool ModelLoader::loadTexture(const std::string& filename) {
std::ifstream textureFile(filename, std::ios::binary);
if (!textureFile.is_open()) {
std::cerr << "Error: Could not open texture file." << std::endl;
return false;
}
BITMAPFILEHEADER fileHeader;
textureFile.read(reinterpret_cast<char*>(&fileHeader), sizeof(fileHeader));
BITMAPINFOHEADER infoHeader;
textureFile.read(reinterpret_cast<char*>(&infoHeader), sizeof(infoHeader));
// Print some debugging information about the texture
std::cout << "Texture width: " << infoHeader.biWidth << std::endl;
std::cout << "Texture height: " << infoHeader.biHeight << std::endl;
std::cout << "Texture bit count: " << infoHeader.biBitCount << std::endl;
int width = infoHeader.biWidth;
int height = infoHeader.biHeight;
int imageSize = width * height * (infoHeader.biBitCount / 8);
unsigned char* data = new unsigned char[imageSize];
textureFile.seekg(fileHeader.bfOffBits);
textureFile.read(reinterpret_cast<char*>(data), imageSize);
textureFile.close();
textureID = createTexture(data, width, height);
delete[] data;
return textureID != 0;
}
GLuint ModelLoader::createTexture(const unsigned char* data, int width, int height) {
GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
// Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
// Upload texture data
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, 0x80E0, GL_UNSIGNED_BYTE, data);
// Unbind the texture
glBindTexture(GL_TEXTURE_2D, 0);
return textureID;
}