Пример #1
0
void SvgTreeBuilder::line(clan::DomElement &e)
{
	float x0 = (float)SvgAttributeReader::single_length(e, "x0");
	float y0 = (float)SvgAttributeReader::single_length(e, "y0");
	float x1 = (float)SvgAttributeReader::single_length(e, "x1");
	float y1 = (float)SvgAttributeReader::single_length(e, "y1");
	auto path = clan::Path::line(x0, y0, x1, y1);
	render_path(path, e);
}
Пример #2
0
void SvgTreeBuilder::circle(clan::DomElement &e)
{
	float cx = (float)SvgAttributeReader::single_length(e, "cx");
	float cy = (float)SvgAttributeReader::single_length(e, "cy");
	float r = (float)SvgAttributeReader::single_length(e, "r");
	if (r != 0.0f)
	{
		auto path = clan::Path::circle(cx, cy, r);
		render_path(path, e);
	}
}
Пример #3
0
void SvgTreeBuilder::ellipse(clan::DomElement &e)
{
	float cx = (float)SvgAttributeReader::single_length(e, "cx");
	float cy = (float)SvgAttributeReader::single_length(e, "cy");
	float rx = (float)SvgAttributeReader::single_length(e, "rx");
	float ry = (float)SvgAttributeReader::single_length(e, "ry");
	if (rx != 0.0f && ry != 0.0f)
	{
		auto path = clan::Path::ellipse(cx, cy, rx, ry);
		render_path(path, e);
	}
}
Пример #4
0
void SvgTreeBuilder::rect(clan::DomElement &e)
{
	float x = (float)SvgAttributeReader::single_length(e, "x");
	float y = (float)SvgAttributeReader::single_length(e, "y");
	float width = (float)SvgAttributeReader::single_length(e, "width");
	float height = (float)SvgAttributeReader::single_length(e, "height");
	if (width != 0.0f && height != 0.0f)
	{
		auto path = clan::Path::rect(x, y, width, height);
		render_path(path, e);
	}
}
Пример #5
0
void raster_raster(Raster *raster) {
	StyleMachine _m, *m = &_m;
	PathElement *e;

	memset(m, 0, sizeof(*m));
	memset(raster->buffer, 255, raster->size[0]*raster->size[1]*4);

	for (e=raster->renderlist.first; e; e=e->next) {
		if (e->type == PATH_PATH) {
			render_path(m, raster, (Path*)e);
		} else {
			render_segment(raster, (PathSegment*)e);
		}
	}
}
Пример #6
0
bool SkDrawPathCommand::render(SkCanvas* canvas) const {
    render_path(canvas, fPath);
    return true;
}
Пример #7
0
void SvgTreeBuilder::path(clan::DomElement &e)
{
	SvgAttributeReader data(e, "d");

	clan::Path path;

	try
	{
		double last_x = 0.0;
		double last_y = 0.0;
		double last_cp_x = 0.0f;
		double last_cp_y = 0.0f;

		while (!data.is_end())
		{
			char command = data.get_path_command();
			bool absolute = (command >= 'A' && command <= 'Z');
			if (command != 'Z' && command != 'z' && !data.is_number()) data.parse_error("unexpected path data");
			switch (command)
			{
			case 'M': // Move to (abs)
			case 'm': // Move to (rel)
			{
				double mx = data.get_sequence_number();
				double my = data.get_sequence_number();
				if (!absolute)
				{
					mx += last_x;
					my += last_y;
				}
				path.move_to((float)mx, (float)my);
				last_x = mx;
				last_y = my;
				last_cp_x = last_x;
				last_cp_y = last_y;
				while (data.is_sequence_number())
				{
					double lx = data.get_sequence_number();
					double ly = data.get_sequence_number();
					if (!absolute)
					{
						lx += last_x;
						ly += last_y;
					}
					path.line_to((float)lx, (float)ly);
					last_x = lx;
					last_y = ly;
					last_cp_x = last_x;
					last_cp_y = last_y;
				}
				break;
			}
			case 'Z': // Close path
			case 'z':
				path.close();
				break;
			case 'L': // Line to (abs)
			case 'l': // Line to (rel)
				do
				{
					double x = data.get_sequence_number();
					double y = data.get_sequence_number();
					if (!absolute)
					{
						x += last_x;
						y += last_y;
					}
					path.line_to((float)x, (float)y);
					last_x = x;
					last_y = y;
					last_cp_x = last_x;
					last_cp_y = last_y;
				} while (data.is_sequence_number());
				break;
			case 'H': // Horizontal line to (abs)
			case 'h': // Horizontal line to (rel)
				do
				{
					double x = data.get_sequence_number();
					if (!absolute)
						x += last_x;
					path.line_to((float)x, (float)last_y);
					last_x = x;
					last_cp_x = last_x;
				} while (data.is_sequence_number());
				break;
			case 'V': // Vertical line to (abs)
			case 'v': // Vertical line to (rel)
				do
				{
					double y = data.get_number();
					if (!absolute)
						y += last_y;
					path.line_to((float)last_x, (float)y);
					last_y = y;
					last_cp_y = last_y;
				} while (data.is_sequence_number());
				break;
			case 'C': // Cubic curve to (abs)
			case 'c': // Cubic curve to (rel)
				do
				{
					double x1 = data.get_sequence_number();
					double y1 = data.get_sequence_number();
					double x2 = data.get_sequence_number();
					double y2 = data.get_sequence_number();
					double x = data.get_sequence_number();
					double y = data.get_sequence_number();
					if (!absolute)
					{
						x1 += last_x;
						y1 += last_y;
						x2 += last_x;
						y2 += last_y;
						x += last_x;
						y += last_y;
					}
					path.bezier_to(clan::Pointf((float)x1, (float)y1), clan::Pointf((float)x2, (float)y2), clan::Pointf((float)x, (float)y));
					last_x = x;
					last_y = y;
					last_cp_x = x2;
					last_cp_y = y2;
				} while (data.is_sequence_number());
				break;
			case 'S': // Shorthand/smooth cubic curve to (abs)
			case 's': // Shorthand/smooth cubic curve to (rel)
				do
				{
					double x2 = data.get_sequence_number();
					double y2 = data.get_sequence_number();
					double x = data.get_sequence_number();
					double y = data.get_sequence_number();
					if (!absolute)
					{
						x2 += last_x;
						y2 += last_y;
						x += last_x;
						y += last_y;
					}
					double x1 = last_cp_x + x - last_x;
					double y1 = last_cp_y + y - last_y;
					path.bezier_to(clan::Pointf((float)x1, (float)y1), clan::Pointf((float)x2, (float)y2), clan::Pointf((float)x, (float)y));
					last_x = x;
					last_y = y;
					last_cp_x = x2;
					last_cp_y = y2;
				} while (data.is_sequence_number());
				break;
			case 'Q': // Quadratic curve to (abs)
			case 'q': // Quadratic curve to (rel)
				do
				{
					double x1 = data.get_sequence_number();
					double y1 = data.get_sequence_number();
					double x = data.get_sequence_number();
					double y = data.get_sequence_number();
					if (!absolute)
					{
						x1 += last_x;
						y1 += last_y;
						x += last_x;
						y += last_y;
					}
					path.bezier_to(clan::Pointf((float)x1, (float)y1), clan::Pointf((float)x, (float)y));
					last_x = x;
					last_y = y;
					last_cp_x = x1;
					last_cp_y = y1;
				} while (data.is_sequence_number());
				break;
			case 'T': // Shorthand/smooth quadratic curve to (abs)
			case 't': // Shorthand/smooth quadratic curve to (rel)
				do
				{
					double x = data.get_sequence_number();
					double y = data.get_sequence_number();
					if (!absolute)
					{
						x += last_x;
						y += last_y;
					}
					double x1 = last_cp_x + x - last_x;
					double y1 = last_cp_y + y - last_y;
					path.bezier_to(clan::Pointf((float)x1, (float)y1), clan::Pointf((float)x, (float)y));
					last_x = x;
					last_y = y;
					last_cp_x = x1;
					last_cp_y = y1;
				} while (data.is_sequence_number());
				break;
			case 'A': // Elliptical arc (abs)
			case 'a': // Elliptical arc (rel)
				do
				{
					double rx = data.get_sequence_number();
					double ry = data.get_sequence_number();
					double x_axis_rotate = data.get_sequence_number();
					double y_axis_rotate = data.get_sequence_number();
					double large_arc_flag = data.get_sequence_number();
					double sweep_flag = data.get_sequence_number();
					double x = data.get_sequence_number();
					double y = data.get_sequence_number();
					last_x = x;
					last_y = y;
					last_cp_x = last_x;
					last_cp_y = last_y;
				} while (data.is_sequence_number());
				break;
			default:
				break;
			}
		}
	}
	catch (clan::Exception &)
	{
	}

	render_path(path, e);
}
Пример #8
0
void render_scene(state_t state) {
	srand(time(NULL));
	int TILE_W;
	if(state.gpu_enabled == true) {
		TILE_W = TILE_W_GPU;
	}
	else {
		TILE_W = TILE_W_CPU;
	}
		
	image_t img = {.w=state.image_w, .h=state.image_h, .pixels=(vec3*)malloc(sizeof(vec3)*state.image_w*state.image_h)};

	pthread_t t0;
	if(display) {
		cur_state = state;
		int result;
		result = pthread_create(&t0, NULL, run_display_update, NULL);
		qr_assert(result==0, "root", "Pthread creation failed: %d",result);
		while(window_closed) {
			sleep(0);
		}
	}

	//render image
	//only AO is supported as of now
	int tiles_x = (int)(img.w/(float)TILE_W+0.99999);
	int tiles_y = (int)(img.h/(float)TILE_W+0.99999);
	num_tiles_done = 0;
	num_tiles_total = tiles_x*tiles_y;
	render_done = false;

	if(state.gpu_enabled == false) {
		pthread_t t1;
		int result;
		result = pthread_create(&t1, NULL, run_status_update, NULL);
		qr_assert(result==0, "root", "Pthread creation failed: %d",result);
#pragma omp parallel for schedule(dynamic)
		for(int i=0; i<tiles_x*tiles_y; i++) {
			int x = i/tiles_x;
			int y = i%tiles_x;
			int tile_w,tile_h;
			if(x == tiles_x-1) {
				tile_w = img.w-TILE_W*(tiles_x-1);
			}
			else {
				tile_w = TILE_W;
			}
			if(y == tiles_y-1) {
				tile_h = img.h-TILE_W*(tiles_y-1);
			}
			else {
				tile_h = TILE_W;
			}
			image_t tile = {.w=tile_w, .h=tile_h, .pixels=(vec3*)malloc(sizeof(vec3)*tile_w*tile_h)};
			memset(tile.pixels, 0, sizeof(vec3)*tile_w*tile_h);
			if(state.renderer == RENDERER_AO) {
				render_ao(state, tile, display, x*TILE_W, y*TILE_W);
			}
			else if(state.renderer == RENDERER_PATH) {
				render_path(state, tile, display, x*TILE_W, y*TILE_W);
			}
			else {
				ERROR("root", "Unknown renderer ID: %d",state.renderer);
			}
			//copy tile to image
			for(int xx=0; xx<tile_w; xx++) {
				for(int yy=0; yy<tile_h; yy++) {
					img.pixels[(xx+x*tile_w)+(yy+y*tile_h)*img.w] = tile.pixels[xx+yy*tile_w];
				}
			}

#pragma omp atomic
			num_tiles_done++;
		}
		render_done = true;
		pthread_join(t1, NULL);
	}
	else {
		switch(state.renderer) {
			case RENDERER_AO:
				init_ao_gpu(state, TILE_W, TILE_W);
				break;
			case RENDERER_PATH:
				init_path_gpu(state, TILE_W, TILE_W);
				break;
		};
		for(int i=0; i<tiles_x*tiles_y; i++) {
			int x = i/tiles_x;
			int y = i%tiles_x;
			int tile_w,tile_h;
			if(x == tiles_x-1) {
				tile_w = img.w-TILE_W*(tiles_x-1);
			}
			else {
				tile_w = TILE_W;
			}
			if(y == tiles_y-1) {
				tile_h = img.h-TILE_W*(tiles_y-1);
			}
			else {
				tile_h = TILE_W;
			}
			image_t tile = {.w=tile_w, .h=tile_h, .pixels=(vec3*)malloc(sizeof(vec3)*tile_w*tile_h)};
			memset(tile.pixels, 0, sizeof(vec3)*tile_w*tile_h);
			if(state.renderer == RENDERER_AO) {
				render_ao_gpu(state, tile, display, x*TILE_W, y*TILE_W);
			}
			else if(state.renderer == RENDERER_PATH) {
				render_path_gpu(state, tile,display, x*TILE_W, y*TILE_W);
			}
			else {
				ERROR("root", "Unknown renderer ID: %d",state.renderer);
			}
			//copy tile to image
			for(int xx=0; xx<tile_w; xx++) {
				for(int yy=0; yy<tile_h; yy++) {
					img.pixels[(xx+x*tile_w)+(yy+y*tile_h)*img.w] = tile.pixels[xx+yy*tile_w];
				}
			}
			printf("%c[2K\rTiles: %d/%d",27,i,num_tiles_total);

		}
		switch(state.renderer) {
			case RENDERER_AO:
				exit_ao_gpu();
				break;
			case RENDERER_PATH:
				exit_path_gpu();
		};
		render_done = true;
	}

	printf("Done rendering\n");

	if(display) {
		display_image(img,0,0);
	}

	//write image
	write_image(state.outfile, img);

        if(display) {
                pthread_join(t0, NULL);
        }


	free(img.pixels);
}

int main(int argc, char** argv) {

	char* ofile_override = NULL;

	char** input_files = (char**)malloc(sizeof(char*));
	int n_input_files = 0;

	//parse command line arguments
	{
		int i = 1;
		while(i<argc) {
			if(argv[i][0] == '-') {
				//it is a flag
				switch(argv[i][1]) {
					case 'o':
						//override all output files
						i++;
						ofile_override = argv[i];
						break;
					case 'd':
						//no graphics
						i++;
						display = false;
						break;
					default:
						ERROR("root", "Invalid flag: %s", argv[i]);
				}
			}
			else {
				//input file
				input_files[n_input_files] = argv[i];
				n_input_files++;
				input_files = (char**)realloc(input_files, sizeof(char*)*n_input_files);
			}
			i++;
		}
	}

	//parse input files
	for(int i=0; i<n_input_files; i++) {
		printf("Parsing file %s\n", input_files[i]);

		state_t state = parse_file(input_files[i]);

		if(ofile_override) state.outfile = ofile_override;

#ifdef DEBUG
		//print summary
		printf("Summary:\n output file: %s\n spp: %d\n width: %d\n height: %d\n primitives: %d\n", state.outfile, state.spp, state.image_w, state.image_h, state.n_primitives);
#else
		printf("primitives: %d\nwidth: %d\nheight: %d\n", state.n_primitives, state.image_w, state.image_h);
#endif

		//construct bvh
		construct_bvh(&state);

		//render scene
		render_scene(state);
	}

	return 0;
}