#include <SDL.h>
#include <filament/Engine.h>
#include <filament/FilamentAPI.h>
#include <filament/LightManager.h>
#include <filament/RenderableManager.h>
#include <filament/Scene.h>
#include <filament/View.h>
#include <thread>
#include <utils/EntityManager.h>
#include <filament/TransformManager.h>
#include <math/norm.h>
#include <vector>
#include <fstream>
#include "app/MeshAssimp.h"
#include <filamat/MaterialBuilder.h>
#include <private/filament/Variant.h>
using namespace filament;
using namespace utils;
using namespace math;
using namespace std;
SDL_Window* createSDLwindow(int x, int y, int w, int h) {
const uint32_t windowFlags =
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
SDL_Window* win =
SDL_CreateWindow("Hello World!", x, y, w, h, windowFlags);
if (win == nullptr) {
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return NULL;
}
return win;
}
#include "NativeWindowHelper.h"
#include <utils/Panic.h>
#include <SDL_syswm.h>
std::ifstream::pos_type getFileSize(const char* filename) {
std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
return in.tellg();
}
int main(int argc, char** argv) {
int winPosX = 100;
int winPosY = 100;
int winWidth = 1280;
int winHeight = 720;
const uint32_t windowFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
SDL_Window *window = createSDLwindow(winPosX, winPosY, winWidth, winHeight);
Engine *engine = Engine::create();
SwapChain *swapChain = engine->createSwapChain(::getNativeWindow(window));
Renderer *renderer = engine->createRenderer();
Camera *camera = engine->createCamera();
View *view = engine->createView();
Scene *scene = engine->createScene();
view->setCamera(camera);
// Determine the current size of the window in physical pixels.
uint32_t w, h;
SDL_GL_GetDrawableSize(window, (int *)&w, (int *)&h);
camera->setProjection(45.0, double(w) / h, 0.1, 50, Camera::Fov::VERTICAL);
view->setViewport({ 0, 0, w, h });
view->setScene(scene);
std::string shader = "\
void material(inout MaterialInputs material) {\
prepareMaterial(material);\
material.baseColor.rgb = materialParams.baseColor;\
material.metallic = materialParams.metallic;\
material.roughness = materialParams.roughness;\
material.reflectance = materialParams.reflectance;\
}\
";
filamat::MaterialBuilder::init();
filamat::MaterialBuilder builder = filamat::MaterialBuilder()
.name("DefaultMaterial")
.material(shader.c_str())
.shading(Shading::LIT)
.printShaders(true)
.variantFilter(filament::Variant::SHADOW_RECEIVER | filament::Variant::SKINNING | filament::Variant::DYNAMIC_LIGHTING)
.targetApi(filamat::MaterialBuilder::TargetApi::OPENGL)
.optimization(filamat::MaterialBuilder::Optimization::NONE)
;
builder.parameter(filamat::MaterialBuilder::UniformType::FLOAT3, "baseColor");
builder.parameter(filamat::MaterialBuilder::UniformType::FLOAT, "metallic");
builder.parameter(filamat::MaterialBuilder::UniformType::FLOAT, "roughness");
builder.parameter(filamat::MaterialBuilder::UniformType::FLOAT, "reflectance");
filamat::Package pkg = builder.build();
Material *material = nullptr;
MaterialInstance *materialInstance = nullptr;
material = Material::Builder().package(pkg.getData(), pkg.getSize()).build(*engine);
materialInstance = material->createInstance();
Entity light = EntityManager::get().create();
LightManager::Builder(LightManager::Type::SUN)
.color(Color::toLinear<ACCURATE>(sRGBColor(0.98f, 0.92f, 0.89f)))
.intensity(110000)
.direction({ 0.7, -1, -0.8 })
.sunAngularRadius(1.9f)
.castShadows(true)
.build(*engine, light);
scene->addEntity(light);
string modelFilename = "assets/models/monkey/monkey.obj";
std::map<std::string, MaterialInstance *> materialInstanceMaps;
materialInstanceMaps["DefaultMaterial"] = materialInstance;
materialInstanceMaps["DefaultMaterial"]->setParameter("baseColor", float3{ 1.0f, 0.0f, 0.0f });
materialInstanceMaps["DefaultMaterial"]->setParameter("metallic", 0.0f);
materialInstanceMaps["DefaultMaterial"]->setParameter("roughness", 0.4f);
materialInstanceMaps["DefaultMaterial"]->setParameter("reflectance", 0.5f);
std::unique_ptr<MeshAssimp> meshSet = std::make_unique<MeshAssimp>(*engine);
meshSet->addFromFile(modelFilename, materialInstanceMaps, true);
mat4f origTransform = math::mat4f::translation(float3{ 0, -1, -100 }) * mat4f::rotation(0.5 * M_PI, float3{ 1, 0, 0 });
auto &rcm = engine->getRenderableManager();
auto &tcm = engine->getTransformManager();
for (auto renderable : meshSet->getRenderables()) {
if (rcm.hasComponent(renderable)) {
auto ti = tcm.getInstance(renderable);
tcm.setTransform(ti, mat4f{ mat3f(1), float3(0.0f, 0.0f, -4.0f) } *
tcm.getWorldTransform(ti));
scene->addEntity(renderable);
}
}
bool run = true;
double g_discoAngle = 0;
double g_discoAngularSpeed = 1;
double lastTime = 0;
float3 pos = 0;
while (run) {
if (renderer->beginFrame(swapChain)) {
renderer->render(view);
renderer->endFrame();
}
double now = (double)SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency();
double dT = now - lastTime;
SDL_Event event;
int numEvents = 0;
while (SDL_PollEvent(&event) && numEvents < 16) {
switch (event.type) {
case SDL_QUIT:
run = false;
break;
}
numEvents++;
}
SDL_Delay(16);
g_discoAngle += g_discoAngularSpeed * dT;
lastTime = now;
}
// ------------------------------------------- clear
for (auto &item : materialInstanceMaps) {
auto materialInstance = item.second;
engine->destroy(materialInstance);
}
meshSet.reset(nullptr);
engine->destroy(material);
engine->destroy(view);
engine->destroy(scene);
engine->destroy(renderer);
engine->destroy(camera);
EntityManager &em = EntityManager::get();
engine->destroy(light);
em.destroy(light);
Engine::destroy(&engine);
engine = nullptr;
return 0;
}