Handle loading of embedded textures
authorLuke Lau <luke_lau@icloud.com>
Sun, 9 Feb 2020 18:02:25 +0000 (18:02 +0000)
committerLuke Lau <luke_lau@icloud.com>
Sun, 9 Feb 2020 18:02:25 +0000 (18:02 +0000)
12 files changed:
.gitignore
Makefile
cocoa.h [deleted file]
cocoa.mm [deleted file]
compile_flags.txt [new file with mode: 0644]
image.cpp
image.hpp
main.cpp
material.cpp
material.hpp
model.cpp
models/newtonsCradle.blend

index de0f0b82928abab3e828dfedc0105ebcbb5990ef..e45b329cb3490e2b7238ac798da1df1bd9b0fdcf 100644 (file)
@@ -16,3 +16,5 @@ bin
 _minted-report
 .vim
 *.blend1
+*.o
+.clangd
index 98f6c27a9400483d0295fd7443136da27943e7cb..05d7b83b50de1502dd68b1599b187a9ffb611d72 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,10 @@
-all: main
+all: bin/main
 
-main:
-       clang++ -g --std=c++17 *.cpp *.mm -L../assimp/lib -lassimp -I../assimp/include -framework OpenGL -framework glut -framework CoreGraphics -framework CoreFoundation -framework Cocoa -framework ImageIO -lglew -o bin/main
+bin/main: model.o material.o image.o skybox.o program.o main.cpp
+       clang++ -g --std=c++17 $^ -I../assimp/include -L../assimp/lib -lassimp \
+               -I/usr/local/include -L/usr/local/lib \
+               -framework OpenGL -framework glut -framework CoreGraphics -framework CoreFoundation -framework ImageIO -lglew -o $@
        ctags *.cpp
+
+%.o: %.cpp
+       clang++ -g --std=c++17 -I/usr/local/include -c $< -o $@
diff --git a/cocoa.h b/cocoa.h
deleted file mode 100644 (file)
index f7e42ab..0000000
--- a/cocoa.h
+++ /dev/null
@@ -1 +0,0 @@
-void makeRetina();
diff --git a/cocoa.mm b/cocoa.mm
deleted file mode 100644 (file)
index 6658948..0000000
--- a/cocoa.mm
+++ /dev/null
@@ -1,7 +0,0 @@
-#import <Cocoa/Cocoa.h>
-
-void makeRetina() {
-       NSWindow *window = [NSApp orderedWindows][0];
-       NSView *view = [window contentView];
-       [view setWantsBestResolutionOpenGLSurface: true];
-}
diff --git a/compile_flags.txt b/compile_flags.txt
new file mode 100644 (file)
index 0000000..5617deb
--- /dev/null
@@ -0,0 +1,2 @@
+-std=c++17
+-I/usr/local/include/
index e3c5cbdb81fe2355c63c9452b25f8a92adec68f9..6c09fa31caaca7335e18f302fb687d6393a85dc5 100644 (file)
--- a/image.cpp
+++ b/image.cpp
@@ -6,7 +6,18 @@ Image::Image(const std::string &path) {
        CFURLRef url = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, false);
        CGImageSourceRef source = CGImageSourceCreateWithURL(url, NULL);
        CGImageRef ref = CGImageSourceCreateImageAtIndex(source, 0, NULL);
+       initWithImageRef(ref);
+       CGImageRelease(ref);
+}
 
+Image::Image(const unsigned char *data, size_t length) {
+       CGDataProviderRef dpRef = CGDataProviderCreateWithData(NULL, data, length, NULL);
+       CGImageRef ref = CGImageCreateWithJPEGDataProvider(dpRef, NULL, false, kCGRenderingIntentDefault);
+       initWithImageRef(ref);
+       CGImageRelease(ref);
+}
+
+void Image::initWithImageRef(CGImageRef ref) {
        _width = CGImageGetWidth(ref), _height = CGImageGetHeight(ref);
        info = CGImageGetBitmapInfo(ref);
        alphaInfo = CGImageGetAlphaInfo(ref);
@@ -14,8 +25,6 @@ Image::Image(const std::string &path) {
        bitsPerComponent = CGImageGetBitsPerComponent(ref);
 
        dataRef = CGDataProviderCopyData(CGImageGetDataProvider(ref));
-       CGImageRelease(ref);
-
 }
 
 unsigned char *Image::data() const {
index caa951c4974e4b26187f2306dcd5b562d90a495b..6864553c316b702efb124e375f0efa586e5a956e 100644 (file)
--- a/image.hpp
+++ b/image.hpp
@@ -11,6 +11,7 @@
 class Image {
        public:
                Image(const std::string &path);
+               Image(const unsigned char *data, size_t length);
                ~Image();
                unsigned char *data() const;
                GLfloat width() const;
@@ -20,6 +21,7 @@ class Image {
                GLenum type() const;
        private:
                #ifdef __APPLE__
+               void initWithImageRef(CGImageRef ref);
                CFDataRef dataRef;
                CGBitmapInfo info;
                CGImageAlphaInfo alphaInfo;
index a82fc962f53e57ccf5a461348b245aa3887c9564..0b7cb229dd745e09d405234bfe89b5f107eab389 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -5,7 +5,6 @@
 #include <vector>
 #ifdef __APPLE__
 #include <GL/glew.h>
-#include "cocoa.h"
 #else
 #include <OpenGL/glew.h>
 #endif
@@ -187,7 +186,7 @@ void init() {
 
        pbrProg = new Program("pbrvert.glsl", "pbrfrag.glsl");
        glUseProgram(pbrProg->progId);
-       pbr = new Model("models/newtonsCradle.gltf", *pbrProg);
+       pbr = new Model("models/newtonsCradle.glb", *pbrProg);
 
        glEnable(GL_DEPTH_TEST); 
        glEnable(GL_CULL_FACE); 
@@ -287,7 +286,6 @@ int main(int argc, char** argv) {
        glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGB|GLUT_3_2_CORE_PROFILE);
        glutInitWindowSize(windowWidth, windowHeight);
        int win = glutCreateWindow("Physically Based Rendering");
-       makeRetina();
        glutDisplayFunc(display);
        glutReshapeFunc(reshape);
 
index 3da687c3a87d0c40d20577a06848be7f6a520d2e..c059226009dfeef2e328238bb50a3286d0bcc47f 100644 (file)
@@ -1,29 +1,53 @@
 #include "material.hpp"
 #include "image.hpp"
 
-Material::Material(const aiMaterial &ai, GLuint progId): progId(progId) {
+Material::Material(const aiMaterial &ai, const aiScene &scene, GLuint progId): progId(progId) {
+       aiString name;
+       ai.Get(AI_MATKEY_NAME, name);   
+       if (name == aiString("default material")) {
+               abort();
+       }
+
        aiString path;
        ai.GetTexture(aiTextureType_DIFFUSE, 1, &path);
-       albedo = new Texture(std::string(path.C_Str()));
+       albedo = new Texture(path, scene);
        path = "";
 
        ai.GetTexture(aiTextureType_NORMALS, 0, &path);
-       normal = new Texture(std::string(path.C_Str()));
+       normal = new Texture(path, scene);
        path = "";
 
-       ai.GetTexture(aiTextureType_UNKNOWN, 0, &path);
-       metallicRoughness = new Texture(std::string(path.C_Str()));
+       ai.GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE, 0, &path);
+       metallicRoughness = new Texture(path, scene);
        path = "";
        
        ai.GetTexture(aiTextureType_LIGHTMAP, 0, &path);
-       ambientOcclusion = new Texture(std::string(path.C_Str()));
+       ambientOcclusion = new Texture(path, scene);
 }
 
-Material::Texture::Texture(const std::string &fileName) {
+Material::Texture::Texture(const aiString fileName, const aiScene &scene) {
        glGenTextures(1, &texId);
        glBindTexture(GL_TEXTURE_2D, texId);
-       Image img("models/" + fileName);
+       
+       std::string path;
+       unsigned char *data;
+       if (fileName.data[0] == '*') {
+               // embedded
+               int embIdx = atoi(&fileName.data[1]);
+               aiTexture *texture = scene.mTextures[embIdx];
+               if (texture->mHeight == 0) {
+                       Image img((unsigned char*)texture->pcData, texture->mWidth);
                        glTexImage2D(GL_TEXTURE_2D, 0, img.internalFormat(), img.width(), img.height(), 0, img.format(), img.type(), img.data());
+               } else {
+                       fprintf(stderr, "TODO: handle uncompressed embedded textures");
+                       abort();
+               }
+       } else {
+               // not embedded
+               Image img("models/" + std::string(fileName.C_Str()));
+               glTexImage2D(GL_TEXTURE_2D, 0, img.internalFormat(), img.width(), img.height(), 0, img.format(), img.type(), img.data());
+       }
+
        glGenerateMipmap(GL_TEXTURE_2D);
 }
 
index 7735f630206b1abf9c5f7a4ecfb03abee5eec154..c814c9eab8451bc23b0a418b8244b69045b71e10 100644 (file)
@@ -8,7 +8,7 @@
 
 class Material {
        public:
-               Material(const aiMaterial &aiMaterial, GLuint progId);
+               Material(const aiMaterial &aiMaterial, const aiScene &aiScene, GLuint progId);
                void bind() const;
        private:
                GLuint progId;
@@ -16,7 +16,7 @@ class Material {
                ai_real shininess, reflectivity, refractiveIndex, opacity;
 
                struct Texture {
-                       Texture(const std::string &file);
+                       Texture(const aiString file, const aiScene &aiScene);
                        GLuint texId;
                };
                Texture *albedo = nullptr;
index efc7f222b9db70856e362cf50b15549b5d5c4d27..107fda0b321317ab54a145d7e1249c08f340abde 100644 (file)
--- a/model.cpp
+++ b/model.cpp
@@ -314,7 +314,7 @@ Model::Model(const std::string &path, Program p): program(p) {
        // TODO: handle default material inserted at the end by assimp
        for (unsigned int i = 0; i < scene->mNumMaterials - 1; i++) {
                const aiMaterial &material = *scene->mMaterials[i];
-               materials.push_back(Material(material, p.progId));
+               materials.push_back(Material(material, *scene, p.progId));
        }
 
        AnimMap *animMap = new AnimMap();
@@ -343,22 +343,22 @@ Model::Model(const std::string &path, Program p): program(p) {
        root = new Node(*(scene->mRootNode), p.progId, animMap);
 }
 
-void Model::calcBoneTransforms(aiNode &node, glm::mat4 parentTrans = glm::mat4(1), BoneTransforms boneTrans = BoneTransforms()) {
-       glm::mat4 animTrans(1.f);
-       if (animMap->count(std::string(ai.mName.C_Str()))) {
-               for (const Animation anim: animMap->at(std::string(ai.mName.C_Str()))) {
-                       float t = fmod(tick, anim.duration);
-                       for (const aiNodeAnim *nodeAnim: anim.nodeAnims) {
-                               animTrans *= lerpPosition(nodeAnim, t);
-                               animTrans *= lerpRotation(nodeAnim, t);
-                               animTrans *= lerpScaling(nodeAnim, t);
-                       }
-               }
-       }
+/* void Model::calcBoneTransforms(aiNode &node, glm::mat4 parentTrans = glm::mat4(1), BoneTransforms boneTrans = BoneTransforms()) { */
+/*     glm::mat4 animTrans(1.f); */
+/*     if (animMap->count(std::string(ai.mName.C_Str()))) { */
+/*             for (const Animation anim: animMap->at(std::string(ai.mName.C_Str()))) { */
+/*                     float t = fmod(tick, anim.duration); */
+/*                     for (const aiNodeAnim *nodeAnim: anim.nodeAnims) { */
+/*                             animTrans *= lerpPosition(nodeAnim, t); */
+/*                             animTrans *= lerpRotation(nodeAnim, t); */
+/*                             animTrans *= lerpScaling(nodeAnim, t); */
+/*                     } */
+/*             } */
+/*     } */
        
 
-       glm::mat4 m = parentTrans * animTrans * aiMatrixToMat4(ai.mTransformation) * model;
-}
+/*     glm::mat4 m = parentTrans * animTrans * aiMatrixToMat4(ai.mTransformation) * model; */
+/* } */
 
 void Model::draw(Skybox skybox, const float tick) const {
        glUseProgram(program.progId);
index 1237396f949ac43e6b31c98fc247d76eafe33cf8..28b9c28ceec409b16800652e2823975e217d635e 100644 (file)
Binary files a/models/newtonsCradle.blend and b/models/newtonsCradle.blend differ