#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 "generated/resources/resources.h"
using namespace filament;
using namespace utils;
using namespace math;
using namespace std;
SDL_Window* createSDLwindow() {
const uint32_t windowFlags =
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
SDL_Window* win =
SDL_CreateWindow("Hello World!", 100, 100, 1920, 1080, windowFlags);
if (win == nullptr) {
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return NULL;
}
return win;
}
#include <utils/Panic.h>
#include <SDL_syswm.h>
void* getNativeWindow(SDL_Window* sdlWindow) {
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
ASSERT_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi), "SDL version unsupported!");
HWND win = (HWND)wmi.info.win.window;
return (void*)win;
}
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) {
printf("hello world");
const static uint32_t indices[] = { 0, 1, 2, 2, 3, 0 };
float3 vertices[] = {
{ -10, 0, -10 },
{ -10, 0, 10 },
{ 10, 0, 10 },
{ 10, 0, -10 },
};
short4 tbn = math::packSnorm16(
mat3f::packTangentFrame(math::mat3f{ float3{ 1.0f, 0.0f, 0.0f },
float3{ 0.0f, 0.0f, 1.0f },
float3{ 0.0f, 1.0f, 0.0f } })
.xyzw);
const static math::short4 normals[]{ tbn, tbn, tbn, tbn };
SDL_Window* window = createSDLwindow();
Engine* engine = Engine::create();
SwapChain* swapChain = engine->createSwapChain(getNativeWindow(window));
Renderer* renderer = engine->createRenderer();
TransformManager& tcm = engine->getTransformManager();
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);
VertexBuffer* vertexBuffer =
VertexBuffer::Builder()
.vertexCount(4)
.bufferCount(2)
.attribute(VertexAttribute::POSITION, 0,
VertexBuffer::AttributeType::FLOAT3)
.attribute(VertexAttribute::TANGENTS, 1,
VertexBuffer::AttributeType::SHORT4)
.normalized(VertexAttribute::TANGENTS)
.build(*engine);
vertexBuffer->setBufferAt(
*engine, 0,
VertexBuffer::BufferDescriptor(vertices, vertexBuffer->getVertexCount() * sizeof(vertices[0])));
vertexBuffer->setBufferAt(
*engine, 1,
VertexBuffer::BufferDescriptor(normals, vertexBuffer->getVertexCount() * sizeof(normals[0])));
IndexBuffer* indexBuffer =
IndexBuffer::Builder().indexCount(6).build(*engine);
indexBuffer->setBuffer(
*engine, IndexBuffer::BufferDescriptor(indices, indexBuffer->getIndexCount() * sizeof(uint32_t)));
std::string filename = "generated/material/aiDefaultMat.filamat";
long fileSize = static_cast<long>(getFileSize(filename.c_str()));
if (fileSize <= 0) {
return 1;
}
Material* material = nullptr;
MaterialInstance* materialInstance = nullptr;
std::ifstream in(filename.c_str(), std::ifstream::in);
if (in.is_open()) {
std::vector<char> materialBuffer;
materialBuffer.reserve(static_cast<unsigned long>(fileSize));
in.read(materialBuffer.data(), fileSize);
material = Material::Builder()
.package((void*)materialBuffer.data(), (size_t)fileSize)
.build(*engine);
materialInstance = material->createInstance();
}
materialInstance->setParameter("baseColor", float3{ 0, 0.8, 0 });
materialInstance->setParameter("metallic", 0.0f);
materialInstance->setParameter("roughness", 0.4f);
materialInstance->setParameter("reflectance", 0.5f);
Entity renderable = EntityManager::get().create();
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);
// build a quad
RenderableManager::Builder(1)
.boundingBox({ { -1, -1, -1 }, { 1, 1, 1 } })
.material(0, materialInstance)
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vertexBuffer,
indexBuffer, 0, 6)
.culling(false)
.build(*engine, renderable);
scene->addEntity(renderable);
mat4f origTransform = math::mat4f::translation(float3{ 0, -1, -100 }) * mat4f::rotation(0.5 * M_PI, float3{ 1, 0, 0 });
mat4f camTrans = camera->getModelMatrix();
tcm.setTransform(tcm.getInstance(renderable), origTransform);
constexpr double speed = 100.0;
bool run = true;
double g_discoAngle = 0;
double g_discoAngularSpeed = 1;
double lastTime = 0;
float3 pos = 0;
while (run) {
// beginFrame() returns false if we need to skip a frame
if (renderer->beginFrame(swapChain)) {
// for each View
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);
mat4f transform = mat4f::translation(float3{ 0, -1, -50 }) * mat4f::rotation(g_discoAngle, float3{ 0, 0, 1 });
transform *= origTransform;
tcm.setTransform(tcm.getInstance(renderable), transform);
g_discoAngle += g_discoAngularSpeed * dT;
lastTime = now;
}
Engine::destroy(&engine);
return 0;
}