_minted-report
.vim
*.blend1
+*.o
+.clangd
-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 $@
+++ /dev/null
-void makeRetina();
+++ /dev/null
-#import <Cocoa/Cocoa.h>
-
-void makeRetina() {
- NSWindow *window = [NSApp orderedWindows][0];
- NSView *view = [window contentView];
- [view setWantsBestResolutionOpenGLSurface: true];
-}
--- /dev/null
+-std=c++17
+-I/usr/local/include/
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);
bitsPerComponent = CGImageGetBitsPerComponent(ref);
dataRef = CGDataProviderCopyData(CGImageGetDataProvider(ref));
- CGImageRelease(ref);
-
}
unsigned char *Image::data() const {
class Image {
public:
Image(const std::string &path);
+ Image(const unsigned char *data, size_t length);
~Image();
unsigned char *data() const;
GLfloat width() const;
GLenum type() const;
private:
#ifdef __APPLE__
+ void initWithImageRef(CGImageRef ref);
CFDataRef dataRef;
CGBitmapInfo info;
CGImageAlphaInfo alphaInfo;
#include <vector>
#ifdef __APPLE__
#include <GL/glew.h>
-#include "cocoa.h"
#else
#include <OpenGL/glew.h>
#endif
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);
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);
#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);
}
class Material {
public:
- Material(const aiMaterial &aiMaterial, GLuint progId);
+ Material(const aiMaterial &aiMaterial, const aiScene &aiScene, GLuint progId);
void bind() const;
private:
GLuint progId;
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;
// 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();
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);