Skip to content

Commit a121bb5

Browse files
committed
Models with materials
1 parent 9b985e3 commit a121bb5

10 files changed

Lines changed: 190 additions & 56 deletions

File tree

.vscode/launch.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@
2323
"ignoreFailures": true
2424
}
2525
]
26+
},
27+
{
28+
"name": "(gdb) Launch exporter",
29+
"type": "cppdbg",
30+
"request": "launch",
31+
"program": "${workspaceFolder}/tools/modelexporter",
32+
"args": ["monkey.obj"],
33+
"stopAtEntry": false,
34+
"cwd": "${workspaceFolder}/models",
35+
"environment": [],
36+
"externalConsole": true,
37+
"MIMode": "gdb",
38+
"preLaunchTask": "build_tools",
39+
"setupCommands": [
40+
{
41+
"description": "Enable pretty-printing for gdb",
42+
"text": "-enable-pretty-printing",
43+
"ignoreFailures": true
44+
}
45+
]
2646
}
2747
]
2848
}

.vscode/tasks.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@
1414
"kind": "build",
1515
"isDefault": true
1616
}
17+
},
18+
{
19+
"label": "build_tools",
20+
"type": "shell",
21+
"command": "g++",
22+
"args": [
23+
"-g", "-std=c++11", "tools/modelexporter.cpp", "-o", "tools/modelexporter", "-D", "_DEBUG", "-lassimp"
24+
],
25+
"group": {
26+
"kind": "build",
27+
"isDefault": true
28+
}
1729
}
1830
]
1931
}

main.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,16 @@ int main(int argc, char** argv) {
8282

8383
Shader shader("shaders/basic.vs", "shaders/basic.fs");
8484
shader.bind();
85-
Material material = {};
86-
material.diffuse = {0.4f, 0.2f, 0.1f};
87-
//material.specular = material.diffuse;
88-
//material.shininess = 4.0f;
89-
Mesh mesh("models/monkey.bmf", material, &shader);
85+
86+
Model monkey;
87+
monkey.init("models/tree.bmf", &shader);
9088

9189
uint64 perfCounterFrequency = SDL_GetPerformanceFrequency();
9290
uint64 lastCounter = SDL_GetPerformanceCounter();
9391
float32 delta = 0.0f;
9492

9593
glm::mat4 model = glm::mat4(1.0f);
96-
model = glm::scale(model, glm::vec3(1.2f));
94+
model = glm::scale(model, glm::vec3(0.1f));
9795

9896
FloatingCamera camera(90.0f, 800.0f, 600.0f);
9997
camera.translate(glm::vec3(0.0f, 0.0f, 5.0f));
@@ -210,7 +208,7 @@ int main(int argc, char** argv) {
210208
GLCALL(glUniformMatrix4fv(modelViewProjMatrixLocation, 1, GL_FALSE, &modelViewProj[0][0]));
211209
GLCALL(glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, &modelView[0][0]));
212210
GLCALL(glUniformMatrix4fv(invModelViewLocation, 1, GL_FALSE, &invModelView[0][0]));
213-
mesh.render();
211+
monkey.render();
214212

215213
SDL_GL_SwapWindow(window);
216214

mesh.h

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,10 @@ struct Material {
1616

1717
class Mesh {
1818
public:
19-
Mesh(const char* filename, Material material, Shader* shader) {
19+
Mesh(std::vector<Vertex>& vertices, uint64 numVertices, std::vector<uint32>& indices, uint64 numIndices, Material material, Shader* shader) {
2020
this->material = material;
2121
this->shader = shader;
22-
23-
std::vector<Vertex> vertices;
24-
uint64 numVertices = 0;
25-
26-
std::vector<uint32> indices;
27-
numIndices = 0;
28-
29-
std::ifstream input = std::ifstream(filename, std::ios::in | std::ios::binary);
30-
input.read((char*)&numVertices, sizeof(uint64));
31-
input.read((char*)&numIndices, sizeof(uint64));
32-
33-
for(uint64 i = 0; i < numVertices; i++) {
34-
Vertex vertex;
35-
input.read((char*)&vertex.position.x, sizeof(float));
36-
input.read((char*)&vertex.position.y, sizeof(float));
37-
input.read((char*)&vertex.position.z, sizeof(float));
38-
input.read((char*)&vertex.normal.x, sizeof(float));
39-
input.read((char*)&vertex.normal.y, sizeof(float));
40-
input.read((char*)&vertex.normal.z, sizeof(float));
41-
vertices.push_back(vertex);
42-
}
43-
for(uint64 i = 0; i < numIndices; i++) {
44-
uint32 index;
45-
input.read((char*)&index, sizeof(uint32));
46-
indices.push_back(index);
47-
}
22+
this->numIndices = numIndices;
4823

4924
vertexBuffer = new VertexBuffer(vertices.data(), numVertices);
5025
indexBuffer = new IndexBuffer(indices.data(), numIndices, sizeof(indices[0]));
@@ -77,4 +52,63 @@ class Mesh {
7752
int specularLocation;
7853
int emissiveLocation;
7954
int shininessLocation;
55+
};
56+
57+
class Model {
58+
public:
59+
void init(const char* filename, Shader* shader) {
60+
uint64 numMeshes = 0;
61+
std::ifstream input = std::ifstream(filename, std::ios::in | std::ios::binary);
62+
if(!input.is_open()) {
63+
std::cout << "File not found" << std::endl;
64+
return;
65+
}
66+
67+
input.read((char*)&numMeshes, sizeof(uint64));
68+
69+
for(uint64 i = 0; i < numMeshes; i++) {
70+
Material material;
71+
std::vector<Vertex> vertices;
72+
uint64 numVertices = 0;
73+
std::vector<uint32> indices;
74+
uint64 numIndices = 0;
75+
76+
input.read((char*)&material, sizeof(Material));
77+
input.read((char*)&numVertices, sizeof(uint64));
78+
input.read((char*)&numIndices, sizeof(uint64));
79+
80+
for(uint64 i = 0; i < numVertices; i++) {
81+
Vertex vertex;
82+
input.read((char*)&vertex.position.x, sizeof(float));
83+
input.read((char*)&vertex.position.y, sizeof(float));
84+
input.read((char*)&vertex.position.z, sizeof(float));
85+
input.read((char*)&vertex.normal.x, sizeof(float));
86+
input.read((char*)&vertex.normal.y, sizeof(float));
87+
input.read((char*)&vertex.normal.z, sizeof(float));
88+
vertices.push_back(vertex);
89+
}
90+
for(uint64 i = 0; i < numIndices; i++) {
91+
uint32 index;
92+
input.read((char*)&index, sizeof(uint32));
93+
indices.push_back(index);
94+
}
95+
96+
Mesh* mesh = new Mesh(vertices, numVertices, indices, numIndices, material, shader);
97+
meshes.push_back(mesh);
98+
}
99+
}
100+
101+
void render() {
102+
for(Mesh* mesh : meshes) {
103+
mesh->render();
104+
}
105+
}
106+
107+
~Model() {
108+
for(Mesh* mesh : meshes) {
109+
delete mesh;
110+
}
111+
}
112+
private:
113+
std::vector<Mesh*> meshes;
80114
};

models/credits.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
CREDITS
3+
4+
tree.fbx by JackDotGriff https://jackdotgriff.itch.io/low-poly-nature-assets

models/cube.bmf

336 Bytes
Binary file not shown.

models/monkey.bmf

48 Bytes
Binary file not shown.

models/tree.bmf

6.21 KB
Binary file not shown.

models/tree.fbx

19.2 KB
Binary file not shown.

tools/modelexporter.cpp

Lines changed: 88 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,49 @@ struct Position {
1111
float x, y, z;
1212
};
1313

14-
std::vector<Position> positions;
15-
std::vector<Position> normals;
16-
std::vector<uint32_t> indices;
14+
struct Material {
15+
Position diffuse;
16+
Position specular;
17+
Position emissive;
18+
float shininess;
19+
};
20+
21+
struct Mesh {
22+
std::vector<Position> positions;
23+
std::vector<Position> normals;
24+
std::vector<uint32_t> indices;
25+
Material material;
26+
};
27+
28+
std::vector<Mesh> meshes;
29+
std::vector<Material> materials;
1730

1831
void processMesh(aiMesh* mesh, const aiScene* scene) {
32+
Mesh m;
1933
for(unsigned int i = 0; i < mesh->mNumVertices; i++) {
2034
Position position;
2135
position.x = mesh->mVertices[i].x;
2236
position.y = mesh->mVertices[i].y;
2337
position.z = mesh->mVertices[i].z;
24-
positions.push_back(position);
38+
m.positions.push_back(position);
2539

2640
Position normal;
2741
normal.x = mesh->mNormals[i].x;
2842
normal.y = mesh->mNormals[i].y;
2943
normal.z = mesh->mNormals[i].z;
30-
normals.push_back(normal);
44+
m.normals.push_back(normal);
3145
}
3246

3347
for(unsigned int i = 0; i < mesh->mNumFaces; i++) {
3448
aiFace face = mesh->mFaces[i];
3549
assert(face.mNumIndices == 3);
3650
for(unsigned int j = 0; j < face.mNumIndices; j++) {
37-
indices.push_back(face.mIndices[j]);
51+
m.indices.push_back(face.mIndices[j]);
3852
}
3953
}
54+
55+
m.material = materials[mesh->mMaterialIndex];
56+
meshes.push_back(m);
4057
}
4158

4259
void processNode(aiNode* node, const aiScene* scene) {
@@ -62,6 +79,47 @@ char* getFilename(char* filename) {
6279
return lastSlash;
6380
}
6481

82+
void processMaterials(const aiScene* scene) {
83+
for(uint32_t i = 0; i < scene->mNumMaterials; i++) {
84+
Material mat;
85+
aiMaterial* material = scene->mMaterials[i];
86+
87+
aiColor3D diffuse(0.0f, 0.0f, 0.0f);
88+
if(AI_SUCCESS != material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse)) {
89+
// No diffuse color
90+
}
91+
mat.diffuse = {diffuse.r, diffuse.g, diffuse.b};
92+
93+
aiColor3D specular(0.0f, 0.0f, 0.0f);
94+
if(AI_SUCCESS != material->Get(AI_MATKEY_COLOR_SPECULAR, specular)) {
95+
// No specular color
96+
}
97+
mat.specular = {specular.r, specular.g, specular.b};
98+
99+
aiColor3D emissive(0.0f, 0.0f, 0.0f);
100+
if(AI_SUCCESS != material->Get(AI_MATKEY_COLOR_EMISSIVE, emissive)) {
101+
// No emissive color
102+
}
103+
mat.emissive = {emissive.r, emissive.g, emissive.b};
104+
105+
float shininess = 0.0f;
106+
if(AI_SUCCESS != material->Get(AI_MATKEY_SHININESS, shininess)) {
107+
// No shininess
108+
}
109+
mat.shininess = shininess;
110+
111+
float shininessStrength = 1.0f;
112+
if(AI_SUCCESS != material->Get(AI_MATKEY_SHININESS_STRENGTH, shininessStrength)) {
113+
// No shininessStrength
114+
}
115+
mat.specular.x *= shininessStrength;
116+
mat.specular.y *= shininessStrength;
117+
mat.specular.z *= shininessStrength;
118+
119+
materials.push_back(mat);
120+
}
121+
}
122+
65123
int main(int argc, char** argv) {
66124
if(argc <= 0) {
67125
return 1;
@@ -72,12 +130,13 @@ int main(int argc, char** argv) {
72130
}
73131

74132
Assimp::Importer importer;
75-
const aiScene* scene = importer.ReadFile(argv[argc-1], aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_OptimizeMeshes | aiProcess_OptimizeGraph | aiProcess_JoinIdenticalVertices | aiProcess_ImproveCacheLocality);
133+
const aiScene* scene = importer.ReadFile(argv[argc-1], aiProcess_PreTransformVertices | aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_OptimizeMeshes | aiProcess_OptimizeGraph | aiProcess_JoinIdenticalVertices | aiProcess_ImproveCacheLocality);
76134
if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE, !scene->mRootNode) {
77135
std::cout << "Error while loading model with assimp: " << importer.GetErrorString() << std::endl;
78136
return 1;
79137
}
80138

139+
processMaterials(scene);
81140
processNode(scene->mRootNode, scene);
82141

83142
std::string filename = std::string(getFilename(argv[argc-1]));
@@ -86,21 +145,28 @@ int main(int argc, char** argv) {
86145

87146
std::ofstream output(outputFilename, std::ios::out | std::ios::binary);
88147
std::cout << "Writing bmf file..." << std::endl;
89-
uint64_t numVertices = positions.size();
90-
uint64_t numIndices = indices.size();
91-
output.write((char*)&numVertices, sizeof(uint64_t));
92-
output.write((char*)&numIndices, sizeof(uint64_t));
93-
for(uint64_t i = 0; i < numVertices; i++) {
94-
output.write((char*)&positions[i].x, sizeof(float));
95-
output.write((char*)&positions[i].y, sizeof(float));
96-
output.write((char*)&positions[i].z, sizeof(float));
97-
98-
output.write((char*)&normals[i].x, sizeof(float));
99-
output.write((char*)&normals[i].y, sizeof(float));
100-
output.write((char*)&normals[i].z, sizeof(float));
101-
}
102-
for(uint64_t i = 0; i < numIndices; i++) {
103-
output.write((char*)&indices[i], sizeof(uint32_t));
148+
uint64_t numMeshes = meshes.size();
149+
output.write((char*)&numMeshes, sizeof(uint64_t));
150+
for(Mesh& mesh : meshes) {
151+
uint64_t numVertices = mesh.positions.size();
152+
uint64_t numIndices = mesh.indices.size();
153+
output.write((char*)&mesh.material, sizeof(Material));
154+
155+
output.write((char*)&numVertices, sizeof(uint64_t));
156+
output.write((char*)&numIndices, sizeof(uint64_t));
157+
for(uint64_t i = 0; i < numVertices; i++) {
158+
output.write((char*)&mesh.positions[i].x, sizeof(float));
159+
output.write((char*)&mesh.positions[i].y, sizeof(float));
160+
output.write((char*)&mesh.positions[i].z, sizeof(float));
161+
162+
output.write((char*)&mesh.normals[i].x, sizeof(float));
163+
output.write((char*)&mesh.normals[i].y, sizeof(float));
164+
output.write((char*)&mesh.normals[i].z, sizeof(float));
165+
}
166+
for(uint64_t i = 0; i < numIndices; i++) {
167+
output.write((char*)&mesh.indices[i], sizeof(uint32_t));
168+
}
104169
}
170+
105171
output.close();
106172
}

0 commit comments

Comments
 (0)