Esempio n. 1
0
	TexturePtr LinearGradient::createAsTexture(int width, int height)
	{
		const float w = static_cast<float>(width);
		const float h = static_cast<float>(height);
		
		const float sa = std::abs(std::sin(-angle_ / 180.0f * static_cast<float>(M_PI)));
		const float ca = std::abs(std::cos(-angle_ / 180.0f * static_cast<float>(M_PI)));
		//const float length = std::min(ca < FLT_EPSILON ? FLT_MAX : width / ca, sa < FLT_EPSILON ? FLT_MAX : height / sa);
		//const float length = std::min(ca < FLT_EPSILON ? w : 2.0f * ca * w, sa < FLT_EPSILON ? h : 2.0f * sa * h);

		WindowPtr wnd = WindowManager::getMainWindow();
		CameraPtr cam = std::make_shared<Camera>("ortho_lg", 0, width, 0, height);
		auto grad = createRenderable();
		grad->setCamera(cam);
		grad->setScale(ca < FLT_EPSILON ? w : 2.0f * w / ca, sa < FLT_EPSILON ? h : 2.0f * h / sa);
		grad->setPosition(w/2.0f, h/2.0f);


		RenderTargetPtr rt = RenderTarget::create(width, height);
		rt->getTexture()->setFiltering(-1, Texture::Filtering::LINEAR, Texture::Filtering::LINEAR, Texture::Filtering::POINT);
		rt->getTexture()->setAddressModes(-1, Texture::AddressMode::CLAMP, Texture::AddressMode::CLAMP);
		rt->setCentre(Blittable::Centre::TOP_LEFT);
		rt->setClearColor(Color(0,0,0,0));
		{
			RenderTarget::RenderScope rs(rt, rect(0, 0, width, height));
			grad->preRender(wnd);
			wnd->render(grad.get());
		}
		return rt->getTexture();
	}
Esempio n. 2
0
int main(int argc, char *argv[])
{
#ifdef _MSC_VER
	SetProcessDPIAware();
#endif

	std::list<double> smoothed_time;
	double cumulative_time = 0.0;
	int cnt = 0;

	using namespace KRE;

	SDL::SDL_ptr manager(new SDL::SDL());

	SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);

	WindowManager wm("SDL");

	variant_builder hints;
	hints.add("renderer", "opengl");
	hints.add("dpi_aware", true);
	hints.add("use_vsync", true);
	int neww = 1600, newh = 900;
	//if(!autoWindowSize(neww, newh)) {
	//	LOG_DEBUG("Couldn't get automatic window size. Defaulting to " << neww << "x" << newh);
	//}
	LOG_DEBUG("Creating window of size: " << neww << "x" << newh);
	auto main_wnd = wm.createWindow(neww, newh, hints.build());
	main_wnd->enableVsync(true);
	const float aspect_ratio = static_cast<float>(neww) / newh;

	std::map<std::string, std::string> font_paths;
#if defined(__linux__)
	LOG_DEBUG("setting image file filter to 'images/'");
	Surface::setFileFilter(FileFilterType::LOAD, [](const std::string& fname) { return "images/" + fname; });
	Surface::setFileFilter(FileFilterType::SAVE, [](const std::string& fname) { return "images/" + fname; });
	
	font_paths["FreeSans.ttf"] = "data/fonts/FreeSans.ttf";
#else
	LOG_DEBUG("setting image file filter to '../images/'");
	Surface::setFileFilter(FileFilterType::LOAD, [](const std::string& fname) { return "../images/" + fname; });
	Surface::setFileFilter(FileFilterType::SAVE, [](const std::string& fname) { return "../images/" + fname; });

	font_paths["FreeSans.ttf"] = "../data/fonts/FreeSans.ttf";
#endif
	Font::setAvailableFonts(font_paths);

	/*auto surf = Surface::create("test_image.png");
	for(auto col : *surf) {
		LOG_DEBUG(col.red << "," << col.green << "," << col.blue << "," << col.alpha);
	}*/
	
	set_alpha_masks();	
	
	// XXX should a scenegraph be created from a specific window? It'd solve a couple of issues
	SceneGraphPtr scene = SceneGraph::create("main");
	SceneNodePtr root = scene->getRootNode();
	root->setNodeName("root_node");
	/*auto scenecam = std::make_shared<Camera>("cam0", 0, neww, 0, newh);
	scenecam->attachFrustum(std::make_shared<Frustum>());
	root->attachCamera(scenecam);
	auto sunlight = std::make_shared<Light>("the_sun", glm::vec3(1.0f, 1.0f, 1.0f));
	sunlight->setAmbientColor(Color(1.0f,1.0f,1.0f,1.0f));
	root->attachLight(0, sunlight);*/

	DisplayDevice::getCurrent()->setDefaultCamera(std::make_shared<Camera>("ortho1", 0, neww, 0, newh));

	auto rman = std::make_shared<RenderManager>();
	auto rq = rman->addQueue(0, "opaques");

	/*SquareRenderablePtr square(std::make_shared<SquareRenderable>());
	square->setPosition(600.0f, 400.0f);
	square->setScale(2.0f,2.0f);
	root->attachObject(square);

	auto cairo_canvas = Vector::Context::CreateInstance("cairo", 512, 512);
	cairo_canvas->SetSourceColor(0.0, 1.0, 0.0);
	cairo_canvas->Paint();
	cairo_canvas->Fill();
	auto path = cairo_canvas->NewPath();
	path->Circle(256, 256, 100);
	cairo_canvas->AddPath(path);
	cairo_canvas->SetSourceColor(0.0, 0.0, 1.0);
	cairo_canvas->Fill();
	auto text = cairo_canvas->NewPath();
	text->MoveTo(10, 10);
	text->TextPath("ABCDabcde");
	cairo_canvas->AddPath(text);
	cairo_canvas->Fill();
	cairo_canvas->setOrder(5);
	cairo_canvas->setPosition(256.0f,256.0f);
	cairo_canvas->setColor(1.0f,1.0f,1.0f,1.0f);
	root->attachObject(cairo_canvas);*/

#if defined(__linux__)
	//std::string psys_test_file = "data/psystem1.cfg";
	std::string psys_test_file = "data/psystem2.cfg";
#else
	//std::string psys_test_file = "../data/psystem1.cfg";
	std::string psys_test_file = "../data/psystem4.cfg";
#endif
	try {
		auto psystem = scene->createNode("particle_system_container", json::parse_from_file(psys_test_file));
		//auto particle_cam = std::make_shared<Camera>("particle_cam");
		//particle_cam->lookAt(glm::vec3(0.0f, 10.0f, 20.0f), glm::vec3(0.0f), glm::vec3(0.0f,1.0f,0.0f));
		//psystem->attachCamera(particle_cam);
		//root->attachNode(psystem);
		//auto rt = DisplayDevice::RenderTargetInstance(400, 300);
		//rt->SetClearColor(0.0f,0.0f,0.0f,0.0f);
		//rt->SetDrawRect(rect(400,300,400,300));
		//rt->Create();
		//psystem->AttachRenderTarget(rt);
		//root->AttachObject(rt);
	} catch(json::parse_error& e) {
		LOG_ERROR("parse error: " << e.what());
		throw(e);
	}

#if defined(__linux__)
	std::string shader_test_file = "data/shaders.cfg";
#else
	std::string shader_test_file = "../data/shaders.cfg";
#endif
	ShaderProgram::loadFromVariant(json::parse_from_file(shader_test_file));

/*	auto tex = std::make_shared<SimpleTextureHolder>("card-back.png");
	tex->setDrawRect(rectf(0.0f,0.0f,146.0f,260.0f));
	tex->setPosition(146.0f/2.0f, newh-130.0f);
	tex->setOrder(10);
	root->attachObject(tex);

	// test cloning
	auto new_tex = std::make_shared<SimpleTextureHolder>(*tex);
	new_tex->setOrder(tex->getOrder()+1);
	new_tex->setPosition(neww/2.0f, newh/2.0f);
	root->attachObject(new_tex);

	auto free_surf = Surface::create("editor-tools.png", SurfaceFlags::NO_ALPHA_FILTER);
	//auto free_tex = std::make_shared<FreeTextureHolder>("editor-tools.png");
	auto free_tex = std::make_shared<FreeTextureHolder>(free_surf);
	free_tex->setDrawRect(rectf(0.0f,0.0f,256.0f,256.0f));
	free_tex->setPosition(neww - 256.0f, 0.0f);

	// Test that cache surfaces and textures is working.
	std::vector<std::shared_ptr<FreeTextureHolder>> texture_list;		
	for(int n = 0; n != 100; ++n) {
		auto surf2 = Surface::create("editor-tools.png");
		auto tex1 = std::make_shared<FreeTextureHolder>(surf2);
		texture_list.emplace_back(tex1);
	}

	auto fnt_surf = Font::getInstance()->renderText("test", Color::colorOrange(), 20, false, "FreeSans.ttf");
	auto text_tex = std::make_shared<FreeTextureHolder>(fnt_surf);
	//text_tex->setDrawRect(rect(0, 0, fnt_surf->surfaceWidth(), fnt_surf->surfaceHeight()));
	text_tex->setPosition(fnt_surf->surfaceWidth()/2, fnt_surf->surfaceHeight()/2);
	//text_tex->setPosition(fnt_surf->surfaceWidth()/2, fnt_surf->surfaceHeight()/2);
	//text_tex->setDrawRect(rectf(0.0f, 0.0f, fnt_surf->surfaceWidth(), fnt_surf->surfaceHeight()));
	//text_tex->setDrawRect(rectf(0.0f,0.0f,256.0f,256.0f));
	//text_tex->setPosition(128.0f,128.0f);

	float angle = 1.0f;
	float angle_step = 0.5f;

	auto canvas = Canvas::getInstance();
	canvas->setDimensions(800, static_cast<int>(800/aspect_ratio));

	auto canvas_texture = Texture::createTexture("widgets.png");
	canvas_texture->setFiltering(-1, Texture::Filtering::LINEAR, Texture::Filtering::LINEAR, Texture::Filtering::NONE);
	
	texture_packing_test();

	// render target test.
	auto rt1 = RenderTarget::create(300, 300);
	{
		RenderTarget::RenderScope render_scope(rt1);
		//rt1->setClearColor(Color::colorRed());
		rt1->setClearColor(Color(0,0,0,0));
		rt1->clear();
		canvas->setDimensions(300, 300);
		std::vector<glm::u8vec4> circle_colors2;
		generate_color_wheel(60, &circle_colors2, Color(0,0,0,0), 0.8f, 0.8f);
		canvas->drawSolidCircle(point(150, 150), 150.0f, circle_colors2);
		canvas->drawSolidRect(rect(50, 50, 200, 200), Color::colorGrey());
		canvas->drawSolidCircle(point(150, 150), 20.0f, Color::colorCyan());
		rt1->setCentre(Blittable::Centre::TOP_LEFT);
		rt1->preRender(main_wnd);
		canvas->setDimensions(800, static_cast<int>(800/aspect_ratio));//(neww, newh);
	}

	auto test1 = std::make_shared<FreeTextureHolder>("cave2.png");
	test1->setPosition(0,512);
	auto palette_tex = std::make_shared<FreeTextureHolder>("cave2.png");
	palette_tex->getTexture()->addPalette(1, Surface::create("cave_pearl.png"));
	palette_tex->getTexture()->addPalette(2, Surface::create("cave_mossy.png"));
	
	//auto test1 = std::make_shared<FreeTextureHolder>("sand.png");
	//test1->setPosition(0,512);
	//auto palette_tex = std::make_shared<FreeTextureHolder>("sand.png");
	//palette_tex->getTexture()->addPalette(Surface::create("seaside_stormy.png"));

	palette_tex->getTexture()->setPalette(0);
	//auto palette_tex = std::make_shared<FreeTextureHolder>("checkerboard1.png");
	//palette_tex->getTexture()->addPalette(Surface::create("checkerboard-palette.png"));
	palette_tex->setPosition(0, 0);
	auto palette_cam = std::make_shared<Camera>("palette_cam", 0, 800, 0, 800);
	palette_tex->setCamera(palette_cam);
	test1->setCamera(palette_cam);
	
	//auto rt2 = RenderTarget::create(palette_tex->getTexture()->width(), palette_tex->getTexture()->height());
	//rt2->setCentre(Blittable::Centre::TOP_LEFT);

	// Test code for setting shader uniforms.
	auto water_shader = ShaderProgram::getProgram("water_distort");
	water_distort_uniforms wd;
	uniform_mapping wd_mapping;
	UniformBuffer<water_distort_uniforms> water_uniforms("anura_uniforms", wd);
	wd_mapping["u_anura_tex_map"] = offsetof(water_distort_uniforms, texture);
	wd_mapping["u_anura_mvp_matrix"] = offsetof(water_distort_uniforms, mvp);
	wd_mapping["u_anura_cycle"] = offsetof(water_distort_uniforms, cycle);
	wd_mapping["u_anura_sprite_area"] = offsetof(water_distort_uniforms, sprite_area);
	wd_mapping["u_anura_draw_area"] = offsetof(water_distort_uniforms, draw_area);
	wd_mapping["u_intensity"] = offsetof(water_distort_uniforms, intensity);
	wd_mapping["u_water_area"] = offsetof(water_distort_uniforms, water_area);
	water_uniforms.setMapping(&wd_mapping);
	auto water_tex = SimpleTextureHolder("checkerboard1.png");
	water_tex.setPosition(neww/2, newh/2);
	water_tex.setShader(water_shader);
	water_tex.addUniformBuffer(std::move(water_uniforms));
*/

	variant_builder tmxvar;
	tmxvar.add("tmx", "data/isometric_grass_and_water.tmx");
	auto tiled_map = scene->createNode("tiled_map", tmxvar.build());
	tiled_map->setPosition(main_wnd->width() / 2, 0);
	//tiled::TmxReader tmx_reader(std::dynamic_pointer_cast<tiled::Map>(tiled_map));
	//tmx_reader.parseFile("data/isometric_grass_and_water.tmx");
	//tmx_reader.parseFile("data/hex-mini.tmx");
	//tmx_reader.parseFile("data/sewer_tileset.tmx");
	//tmx_reader.parseFile("data/small_isometric_staggered_grass_and_water.tmx");
	//root->attachNode(tiled_map);

	//auto blue_box = std::make_shared<BlurredBlittable>("blue_box3.png");
	//const int bbox_w = blue_box->getTexture()->width();
	//const int bbox_h = blue_box->getTexture()->height();
	//blue_box->setCentre(Blittable::Centre::TOP_LEFT);
	//blue_box->setPosition(0, 0);
	//blue_box->setCamera(std::make_shared<Camera>("ortho999", 0, bbox_w, 0, bbox_h));
	const int bbox_w = 512;
	const int bbox_h = 256;
	auto sr = std::make_shared<SimpleRenderable>(rect(24, 24, bbox_w-48, bbox_h-48), Color(0, 0, 0, 255));
	CameraPtr box_cam = std::make_shared<Camera>("ortho999", 0, bbox_w, 0, bbox_h);
	sr->setCamera(box_cam);
	RenderTargetPtr rt = RenderTarget::create(bbox_w, bbox_h);
	rt->getTexture()->setFiltering(-1, Texture::Filtering::LINEAR, Texture::Filtering::LINEAR, Texture::Filtering::POINT);
	rt->getTexture()->setAddressModes(-1, Texture::AddressMode::CLAMP, Texture::AddressMode::CLAMP);
	rt->setCentre(Blittable::Centre::TOP_LEFT);
		rt->setClearColor(Color(128,128,128,0));
		rt->apply(rect(0, 0, bbox_w, bbox_h));
		rt->clear();
		//blue_box->preRender(main_wnd);
		//main_wnd->render(blue_box.get());
		sr->preRender(main_wnd);
		main_wnd->render(sr.get());
		rt->unapply();
	//root->attachObject(rt);	
	auto shader_blur = ShaderProgram::getProgram("blur2");
	rt->setShader(shader_blur);
	const int blur_two = shader_blur->getUniform("texel_width_offset");
	const int blur_tho = shader_blur->getUniform("texel_height_offset");
	const int u_gaussian = shader_blur->getUniform("gaussian");
	std::vector<float> gaussian = generate_gaussian(20.0f, 7);//{ 0.05f, 0.09f, 0.12f, 0.15f, 0.16f, 0.15f, 0.12f, 0.09f, 0.05f };
	shader_blur->setUniformDrawFunction([blur_two, blur_tho, bbox_h, gaussian, u_gaussian](ShaderProgramPtr shader){ 
		shader->setUniformValue(u_gaussian, &gaussian[0]);
		shader->setUniformValue(blur_two, 0.0f);
		shader->setUniformValue(blur_tho, 1.0f / (bbox_h - 1.0f));
	});
	//rt->setOrder(1);
	RenderTargetPtr rt2 = RenderTarget::create(bbox_w, bbox_h);
	rt2->setCentre(Blittable::Centre::TOP_LEFT);
	rt2->setClearColor(Color(0,0,0,0));
	{
		rt->setCamera(box_cam);
		RenderTarget::RenderScope rs(rt2, rect(0, 0, bbox_w, bbox_h));
		rt->preRender(main_wnd);
		main_wnd->render(rt.get());

		rt2->setShader(shader_blur);
		const int blur_two = shader_blur->getUniform("texel_width_offset");
		const int blur_tho = shader_blur->getUniform("texel_height_offset");
		shader_blur->setUniformDrawFunction([blur_two, blur_tho, bbox_w](ShaderProgramPtr shader){ 
			shader->setUniformValue(blur_two, 1.0f / (bbox_w - 1.0f));
			shader->setUniformValue(blur_tho, 0.0f);
		});
		//rt->setOrder(1);
		//shader_blur->makeActive();
		//shader_blur->setUniformValue(blur_two, 1.0f / (bbox_w - 1.0f));
		//shader_blur->setUniformValue(blur_tho, 0.0f);
	}
	rt2->setOrder(1);
	root->attachObject(rt2);

	auto sr_blue = std::make_shared<SimpleRenderable>(rect(32, 32, bbox_w-64, bbox_h-64), Color::colorBlue());
	sr_blue->setOrder(999);
	root->attachObject(sr_blue);

	//auto bb2 = std::make_shared<SimpleTextureHolder>("blue_box2.png");
	//root->attachObject(bb2);	
	{
	//"deephelm-explorer.png"
	//root->attachObject(blue_box);
	//auto shader = ShaderProgram::getProgram("blur2");
	//int two = shader->getUniform("texel_width_offset");
	//int tho = shader->getUniform("texel_height_offset");
	//rt->setShader(shader);
	//shader->setUniformValue(two, 0.0f);
	//shader->setUniformValue(tho, 1.0f/(bbox_h-1));
	}

	Uint32 last_tick_time = SDL_GetTicks();

	SDL_Event e;
	bool done = false;
	profile::timer timer;
	while(!done) {
		timer.start();
		while(SDL_PollEvent(&e)) {
			if(e.type == SDL_KEYUP && e.key.keysym.scancode == SDL_SCANCODE_ESCAPE) {
				done = true;
			} else if(e.type == SDL_KEYDOWN) {
				LOG_DEBUG("KEY PRESSED: " << SDL_GetKeyName(e.key.keysym.sym) << " : " << e.key.keysym.sym << " : " << e.key.keysym.scancode);
			} else if(e.type == SDL_QUIT) {
				done = true;
			}
		}

		main_wnd->setClearColor(KRE::Color(255, 255, 255, 255));
		main_wnd->clear(ClearFlags::ALL);

		// Called once a cycle before rendering.
		Uint32 current_tick_time = SDL_GetTicks();
		scene->process((current_tick_time - last_tick_time) / 1000.0f);
		last_tick_time = current_tick_time;

		/*tex->setRotation(angle, glm::vec3(0.0f,0.0f,1.0f));
		new_tex->setRotation(360.0f - angle, glm::vec3(0.0f,0.0f,1.0f));
		cairo_canvas->setRotation(angle, glm::vec3(0.0f,0.0f,1.0f));
		angle += angle_step;
		while(angle >= 360.0f) {
			angle -= 360.0f;
		}

		canvas->blitTexture(rt1->getTexture(), 0.0f, 800-rt1->getTexture()->surfaceWidth(), 0);

		{
			//RenderTarget::RenderScope render_scope(rt2);
			//rt2->setClearColor(Color(0,0,0,0));
			//rt2->clear();
			palette_tex->preRender(main_wnd);
			main_wnd->render(palette_tex.get());

			test1->preRender(main_wnd);
			main_wnd->render(test1.get());
		}
		//rt2->preRender(main_wnd);
		//canvas->blitTexture(rt2->getTexture(), 0.0f, 0, 0);

		static int counter_pal = 0;
		static int pal = -1;
		if(++counter_pal >= 60*2) {
			counter_pal = 0;
			if(++pal >= 2) {
				pal = -1;
			}
			palette_tex->getTexture()->setPalette(pal);
		}

		water_tex.preRender(main_wnd);
		main_wnd->render(&water_tex);*/

		//tiled_map->draw(main_wnd);

		//ModelManager2D mm(400,300);
		scene->renderScene(rman);
		rman->render(main_wnd);

		/*free_tex->preRender(main_wnd);
		main_wnd->render(free_tex.get());

		text_tex->preRender(main_wnd);
		main_wnd->render(text_tex.get());*/

		//canvas->drawSolidCircle(point(canvas->width()/2, canvas->height()/2), 50.0f, Color::colorGold());
		//canvas->drawHollowCircle(pointf(400.0f, 400.0f), 150.0f, 150.0f-1.0f,Color::colorAqua());

		//std::vector<glm::u8vec4> circle_colors;
		//generate_color_wheel(60, &circle_colors, Color(0,0,0,0), 0.1f, 0.1f);
		//canvas->drawSolidCircle(point(400, 300), 150.0f, circle_colors);


		/*{
			Canvas::ModelManager mm(0, 0, 10.0f, 1.0f);
			canvas->drawSolidRect(rect(600, 400, 100, 100), Color::colorCoral());
			{
				Canvas::ModelManager mm(500, 300, 20.0f, 3.0f);*/
				/*mm.setIdentity();
				mm.translate(700, 500);
				mm.translate(-200, -200);
				mm.rotate(20);
				mm.scale(1.5f);
				mm.scale(2.0f);*/
				/*canvas->drawSolidRect(rect(0, 0, 100, 100), Color::colorChartreuse());
			}
		}*/

		/*canvas->blitTexture(canvas_texture, 
			rect(3,4,56,22), 
			0.0f, 
			//rect(800-56, 0, 56, 22), 
			rect(0,0,112,44),
			Color(1.0f,1.0f,1.0f,0.5f));
		canvas->drawSolidRect(rect(100, 100, 100, 100), Color("red"));
		canvas->drawHollowRect(rect(125, 125, 50, 50), Color("blue"));
		canvas->drawLine(point(95,95), point(205,205), Color("yellow"));
		std::vector<glm::vec2> varray;
		//varray.emplace_back(400, 400);
		//varray.emplace_back(500, 500);
		varray.emplace_back(400, 400);
		varray.emplace_back(500, 400);
		varray.emplace_back(400, 400);
		varray.emplace_back(500, 500);
		varray.emplace_back(400, 400);
		varray.emplace_back(400, 500);
		canvas->drawLines(varray, 10.0f, Color("pink"));*/

		double t1 = timer.check();
		if(t1 < 1.0/50.0) {
		//	SDL_Delay(Uint32((1.0/50.0-t1)*1000.0));
		}
		double t = timer.check();

		smoothed_time.push_back(t);
		cumulative_time += t;
		if(++cnt > 10) {
			cnt = 0;
			//LOG_DEBUG("FPS: " << (smoothed_time.size()/cumulative_time) << ", Time: " << t1*1000.0);
			LOG_DEBUG("Draw Time: " << (t * 1000000.0) << " us.");
		}
		if(smoothed_time.size() > 50) {
			cumulative_time -= smoothed_time.front();
			smoothed_time.pop_front();
		}

		main_wnd->swap();
	}
	return 0;
}