Handle opengl internal format + format in image.cpp
[opengl.git] / material.cpp
1 #include "material.hpp"
2 #include "image.hpp"
3 #include <assimp/pbrmaterial.h>
4
5 Material::Material(const aiMaterial &ai, const aiScene &scene, GLuint progId): progId(progId) {
6         aiString name;
7         ai.Get(AI_MATKEY_NAME, name);   
8         if (name == aiString("default material")) {
9                 abort();
10         }
11
12         aiString path;
13         ai.GetTexture(aiTextureType_DIFFUSE, 1, &path);
14         albedo = new Texture(path, scene);
15         path = "";
16
17         ai.GetTexture(aiTextureType_NORMALS, 0, &path);
18         normal = new Texture(path, scene);
19         path = "";
20
21         ai.GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE, &path);
22         metallicRoughness = new Texture(path, scene);
23         path = "";
24         
25         ai.GetTexture(aiTextureType_LIGHTMAP, 0, &path);
26         if (path == aiString("")) {
27                 fprintf(stderr, "Material %s does not have an AO map", name.C_Str());
28                 abort();
29         }
30         ambientOcclusion = new Texture(path, scene);
31 }
32
33 Material::Texture::Texture(const aiString fileName, const aiScene &scene) {
34         glGenTextures(1, &texId);
35         glBindTexture(GL_TEXTURE_2D, texId);
36         
37         std::string path;
38         unsigned char *data;
39         if (fileName.data[0] == '*') {
40                 // embedded
41                 int embIdx = atoi(&fileName.data[1]);
42                 aiTexture *texture = scene.mTextures[embIdx];
43                 if (texture->mHeight == 0) {
44                         Image img((unsigned char*)texture->pcData, texture->mWidth, texture->achFormatHint);
45                         glTexImage2D(GL_TEXTURE_2D, 0, img.internalFormat(), img.width(), img.height(), 0, img.format(), img.type(), img.data());
46                 } else {
47                         fprintf(stderr, "TODO: handle uncompressed embedded textures");
48                         abort();
49                 }
50         } else {
51                 // not embedded
52                 Image img("models/" + std::string(fileName.C_Str()));
53                 glTexImage2D(GL_TEXTURE_2D, 0, img.internalFormat(), img.width(), img.height(), 0, img.format(), img.type(), img.data());
54         }
55
56         glGenerateMipmap(GL_TEXTURE_2D);
57 }
58
59 void Material::bind() const {
60         glUniform1i(glGetUniformLocation(progId, "albedoMap"), 0);
61         glActiveTexture(GL_TEXTURE0);
62         glBindTexture(GL_TEXTURE_2D, albedo->texId);
63
64         glUniform1i(glGetUniformLocation(progId, "normalMap"), 1);
65         glActiveTexture(GL_TEXTURE1);
66         glBindTexture(GL_TEXTURE_2D, normal->texId);
67
68         glUniform1i(glGetUniformLocation(progId, "metallicRoughnessMap"), 2);
69         glActiveTexture(GL_TEXTURE2);
70         glBindTexture(GL_TEXTURE_2D, metallicRoughness->texId);
71
72         glUniform1i(glGetUniformLocation(progId, "aoMap"), 3);
73         glActiveTexture(GL_TEXTURE3);
74         glBindTexture(GL_TEXTURE_2D, ambientOcclusion->texId);
75 }