From: Luke Lau Date: Sun, 9 Feb 2020 18:02:25 +0000 (+0000) Subject: Handle loading of embedded textures X-Git-Tag: cs7gv3-a3~10 X-Git-Url: http://git.lukelau.me/?p=opengl.git;a=commitdiff_plain;h=d381f617bef400fc157edf782008cafb018ed594 Handle loading of embedded textures --- diff --git a/.gitignore b/.gitignore index de0f0b8..e45b329 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ bin _minted-report .vim *.blend1 +*.o +.clangd diff --git a/Makefile b/Makefile index 98f6c27..05d7b83 100644 --- 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 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 index 6658948..0000000 --- a/cocoa.mm +++ /dev/null @@ -1,7 +0,0 @@ -#import - -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 index 0000000..5617deb --- /dev/null +++ b/compile_flags.txt @@ -0,0 +1,2 @@ +-std=c++17 +-I/usr/local/include/ diff --git a/image.cpp b/image.cpp index e3c5cbd..6c09fa3 100644 --- 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 { diff --git a/image.hpp b/image.hpp index caa951c..6864553 100644 --- 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; diff --git a/main.cpp b/main.cpp index a82fc96..0b7cb22 100644 --- a/main.cpp +++ b/main.cpp @@ -5,7 +5,6 @@ #include #ifdef __APPLE__ #include -#include "cocoa.h" #else #include #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); diff --git a/material.cpp b/material.cpp index 3da687c..c059226 100644 --- a/material.cpp +++ b/material.cpp @@ -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); } diff --git a/material.hpp b/material.hpp index 7735f63..c814c9e 100644 --- a/material.hpp +++ b/material.hpp @@ -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; diff --git a/model.cpp b/model.cpp index efc7f22..107fda0 100644 --- 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); diff --git a/models/newtonsCradle.blend b/models/newtonsCradle.blend index 1237396..28b9c28 100644 Binary files a/models/newtonsCradle.blend and b/models/newtonsCradle.blend differ