filament <4> Print Shader


#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;

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值