Blame c++/contourgl/test.cpp

Ivan Mahonin 93cbac
/*
Ivan Mahonin 93cbac
    ......... 2015 Ivan Mahonin
Ivan Mahonin 93cbac
Ivan Mahonin 93cbac
    This program is free software: you can redistribute it and/or modify
Ivan Mahonin 93cbac
    it under the terms of the GNU General Public License as published by
Ivan Mahonin 93cbac
    the Free Software Foundation, either version 3 of the License, or
Ivan Mahonin 93cbac
    (at your option) any later version.
Ivan Mahonin 93cbac
Ivan Mahonin 93cbac
    This program is distributed in the hope that it will be useful,
Ivan Mahonin 93cbac
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Ivan Mahonin 93cbac
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Ivan Mahonin 93cbac
    GNU General Public License for more details.
Ivan Mahonin 93cbac
Ivan Mahonin 93cbac
    You should have received a copy of the GNU General Public License
Ivan Mahonin 93cbac
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
Ivan Mahonin 93cbac
*/
Ivan Mahonin 93cbac
Ivan Mahonin 93cbac
#include <fstream>
Ivan Mahonin 93cbac
#include <iostream>
Ivan Mahonin c7fa36
#include <iomanip>
Ivan Mahonin 93cbac
Ivan Mahonin 93cbac
#include "test.h"
Ivan Mahonin 93cbac
#include "contourbuilder.h"
Ivan Mahonin 8cd87e
#include "triangulator.h"
Ivan Mahonin 49e693
#include "measure.h"
Ivan Mahonin 49e693
#include "utils.h"
Ivan Mahonin d989ab
#include "clrender.h"
Ivan Mahonin 93cbac
Ivan Mahonin 93cbac
Ivan Mahonin 93cbac
using namespace std;
Ivan Mahonin 93cbac
Ivan Mahonin 93cbac
Ivan Mahonin d9c2d9
void Test::draw_contour(
Ivan Mahonin d9c2d9
	Environment &e,
Ivan Mahonin d9c2d9
	int start,
Ivan Mahonin d9c2d9
	int count,
Ivan Mahonin d9c2d9
	const rect<int> bounds,
Ivan Mahonin d9c2d9
	bool even_odd,
Ivan Mahonin d9c2d9
	bool invert,
Ivan Mahonin d9c2d9
	const Color &color
Ivan Mahonin d9c2d9
) {
Ivan Mahonin d9c2d9
	glScissor(bounds.p0.x, bounds.p0.y, bounds.p1.x-bounds.p0.x, bounds.p1.y-bounds.p0.y);
Ivan Mahonin d9c2d9
	glEnable(GL_SCISSOR_TEST);
Ivan Mahonin 49e693
	glEnable(GL_STENCIL_TEST);
Ivan Mahonin 93cbac
Ivan Mahonin 49e693
	// render mask
Ivan Mahonin a04770
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
Ivan Mahonin 49e693
	glClear(GL_STENCIL_BUFFER_BIT);
Ivan Mahonin 49e693
	glStencilFunc(GL_ALWAYS, 0, 0);
Ivan Mahonin 49e693
	if (even_odd) {
Ivan Mahonin 49e693
		glStencilOp(GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);
Ivan Mahonin 93cbac
	} else {
Ivan Mahonin 49e693
		glStencilOpSeparate(GL_FRONT, GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);
Ivan Mahonin 49e693
		glStencilOpSeparate(GL_BACK, GL_DECR_WRAP, GL_DECR_WRAP, GL_DECR_WRAP);
Ivan Mahonin 49e693
	}
Ivan Mahonin 49e693
	e.shaders.simple();
Ivan Mahonin d9c2d9
	glDrawArrays(GL_TRIANGLE_FAN, start, count);
Ivan Mahonin a04770
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
Ivan Mahonin 49e693
Ivan Mahonin 49e693
	// fill mask
Ivan Mahonin 49e693
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
Ivan Mahonin 49e693
	if (!even_odd && !invert)
Ivan Mahonin 49e693
		glStencilFunc(GL_NOTEQUAL, 0, -1);
Ivan Mahonin 49e693
	if (!even_odd &&  invert)
Ivan Mahonin 49e693
		glStencilFunc(GL_EQUAL, 0, -1);
Ivan Mahonin 49e693
	if ( even_odd && !invert)
Ivan Mahonin 49e693
		glStencilFunc(GL_EQUAL, 1, 1);
Ivan Mahonin 49e693
	if ( even_odd &&  invert)
Ivan Mahonin 49e693
		glStencilFunc(GL_EQUAL, 0, 1);
Ivan Mahonin 49e693
Ivan Mahonin 49e693
	e.shaders.color(color);
Ivan Mahonin 49e693
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Ivan Mahonin 49e693
Ivan Mahonin 49e693
	glDisable(GL_STENCIL_TEST);
Ivan Mahonin d9c2d9
	glDisable(GL_SCISSOR_TEST);
Ivan Mahonin 7c6b57
}
Ivan Mahonin 7c6b57
Ivan Mahonin f29469
void Test::load(Data &contours, const std::string &filename) {
Ivan Mahonin 9edf2e
	vector<Vector> groups;
Ivan Mahonin 9edf2e
	groups.push_back(Vector());
Ivan Mahonin 9edf2e
Ivan Mahonin f29469
	ifstream f(("data/" + filename).c_str());
Ivan Mahonin 9edf2e
	int vertices_count = 0;
Ivan Mahonin 9edf2e
	while(f) {
Ivan Mahonin 9edf2e
		string s;
Ivan Mahonin 9edf2e
		f >> s;
Ivan Mahonin 9edf2e
		if (s == "g") {
Ivan Mahonin 9edf2e
			Vector t;
Ivan Mahonin 9edf2e
			f >> t.x >> t.y;
Ivan Mahonin 9edf2e
			groups.push_back(groups.back() + t);
Ivan Mahonin 9edf2e
		} else
Ivan Mahonin 9edf2e
		if (s == "end") {
Ivan Mahonin 9edf2e
			groups.pop_back();
Ivan Mahonin 9edf2e
			if ((int)groups.size() == 1)
Ivan Mahonin 9edf2e
				break;
Ivan Mahonin 9edf2e
		} else
Ivan Mahonin 9edf2e
		if (s == "path") {
Ivan Mahonin 9edf2e
			contours.push_back(ContourInfo());
Ivan Mahonin 9edf2e
			ContourInfo &ci = contours.back();
Ivan Mahonin 9edf2e
			f >> ci.invert
Ivan Mahonin 9edf2e
			  >> ci.antialias
Ivan Mahonin 9edf2e
			  >> ci.evenodd
Ivan Mahonin 9edf2e
			  >> ci.color.r
Ivan Mahonin 9edf2e
			  >> ci.color.g
Ivan Mahonin 9edf2e
			  >> ci.color.b
Ivan Mahonin 9edf2e
			  >> ci.color.a;
Ivan Mahonin 9edf2e
			bool closed = true;
Ivan Mahonin 9edf2e
			while(true) {
Ivan Mahonin 9edf2e
				f >> s;
Ivan Mahonin 9edf2e
				Vector p1;
Ivan Mahonin 9edf2e
				if (s == "M") {
Ivan Mahonin 9edf2e
					f >> p1.x >> p1.y;
Ivan Mahonin 9edf2e
					ci.contour.move_to(p1 + groups.back());
Ivan Mahonin 9edf2e
					closed = false;
Ivan Mahonin 9edf2e
				} else
Ivan Mahonin 9edf2e
				if (s == "L") {
Ivan Mahonin 9edf2e
					f >> p1.x >> p1.y;
Ivan Mahonin 9edf2e
					if (closed) {
Ivan Mahonin 9edf2e
						ci.contour.move_to(p1 + groups.back());
Ivan Mahonin 9edf2e
						closed = false;
Ivan Mahonin 9edf2e
					}
Ivan Mahonin 9edf2e
					ci.contour.line_to(p1 + groups.back());
Ivan Mahonin 9edf2e
				} else
Ivan Mahonin 9edf2e
				if (s == "Z") {
Ivan Mahonin 9edf2e
					ci.contour.close();
Ivan Mahonin 9edf2e
					closed = true;
Ivan Mahonin 9edf2e
				} else
Ivan Mahonin 9edf2e
				if (s == "end") {
Ivan Mahonin 9edf2e
					break;
Ivan Mahonin 9edf2e
				} else {
Ivan Mahonin 9edf2e
					cout << "bug " << s << endl;
Ivan Mahonin 9edf2e
					if (!f) break;
Ivan Mahonin 9edf2e
				}
Ivan Mahonin 9edf2e
			}
Ivan Mahonin 9edf2e
			if (!closed)
Ivan Mahonin 9edf2e
				ci.contour.close();
Ivan Mahonin 9edf2e
			if (ci.color.a < 0.9999)
Ivan Mahonin 9edf2e
				contours.pop_back();
Ivan Mahonin 9edf2e
			else
Ivan Mahonin 9edf2e
				vertices_count += ci.contour.get_chunks().size();
Ivan Mahonin 9edf2e
		} else
Ivan Mahonin 9edf2e
		if (s != "") {
Ivan Mahonin 9edf2e
			cout << "bug " << s << endl;
Ivan Mahonin 9edf2e
		}
Ivan Mahonin 9edf2e
	}
Ivan Mahonin 9edf2e
	if ((int)groups.size() != 1)
Ivan Mahonin 9edf2e
		cout << "bug groups " << groups.size() << endl;
Ivan Mahonin 9edf2e
Ivan Mahonin 9edf2e
	cout << contours.size() << " contours" << endl;
Ivan Mahonin 9edf2e
	cout << vertices_count << " vertices" << endl;
Ivan Mahonin 9edf2e
}
Ivan Mahonin 9edf2e
Ivan Mahonin f29469
void Test::transform(Data &data, const Rect &from, const Rect &to) {
Ivan Mahonin f29469
	for(Data::iterator i = data.begin(); i != data.end(); ++i)
Ivan Mahonin f29469
		i->contour.transform(from, to);
Ivan Mahonin f29469
}
Ivan Mahonin 9edf2e
Ivan Mahonin f29469
void Test::downgrade(Data &from, Data &to) {
Ivan Mahonin f29469
	to = from;
Ivan Mahonin f29469
	Measure t("downgrade");
Ivan Mahonin f29469
	for(Data::iterator i = from.begin(); i != from.end(); ++i)
Ivan Mahonin d9c2d9
		i->contour.downgrade(to[i - from.begin()].contour, Vector(1.f, 1.f));
Ivan Mahonin f29469
}
Ivan Mahonin 93cbac
Ivan Mahonin f29469
void Test::split(Data &from, Data &to) {
Ivan Mahonin f29469
	to = from;
Ivan Mahonin f29469
	Measure t("split");
Ivan Mahonin f29469
	for(Data::iterator i = from.begin(); i != from.end(); ++i)
Ivan Mahonin f29469
		i->contour.split(to[i - from.begin()].contour, Rect(0.f, 0.f, 100000.f, 100000.f), Vector(1.f, 1.f));
Ivan Mahonin f29469
}
Ivan Mahonin 93cbac
Ivan Mahonin f29469
void Test::test_gl_stencil(Environment &e, Data &data) {
Ivan Mahonin d9c2d9
	Vector size = Utils::get_frame_size();
Ivan Mahonin 7c6b57
	GLuint buffer_id = 0;
Ivan Mahonin 7c6b57
	GLuint array_id = 0;
Ivan Mahonin a04770
	vector<vec2f> vertices;
Ivan Mahonin f29469
	vector<int> starts(data.size());
Ivan Mahonin f29469
	vector<int> counts(data.size());
Ivan Mahonin d9c2d9
	vector< rect<int> > bounds(data.size());
Ivan Mahonin f29469
Ivan Mahonin f29469
	vertices.push_back(vec2f(-1.f, -1.f));
Ivan Mahonin f29469
	vertices.push_back(vec2f( 1.f, -1.f));
Ivan Mahonin f29469
	vertices.push_back(vec2f(-1.f,  1.f));
Ivan Mahonin f29469
	vertices.push_back(vec2f( 1.f,  1.f));
Ivan Mahonin f29469
	for(int i = 0; i < (int)data.size(); ++i) {
Ivan Mahonin f29469
		starts[i] = (int)vertices.size();
Ivan Mahonin f29469
		const Contour::ChunkList &chunks = data[i].contour.get_chunks();
Ivan Mahonin d9c2d9
		Rect r(chunks.front().p1, chunks.front().p1);
Ivan Mahonin f29469
		for(Contour::ChunkList::const_iterator j = chunks.begin(); j != chunks.end(); ++j) {
Ivan Mahonin d9c2d9
			vertices.push_back(vec2f(j->p1));
Ivan Mahonin d9c2d9
			r = r.expand(j->p1);
Ivan Mahonin 8de121
		}
Ivan Mahonin f29469
		counts[i] = (int)vertices.size() - starts[i];
Ivan Mahonin d9c2d9
		bounds[i].p0.x = (int)floor((r.p0.x + 1.0)*0.5*size.x);
Ivan Mahonin d9c2d9
		bounds[i].p0.y = (int)floor((r.p0.y + 1.0)*0.5*size.y);
Ivan Mahonin d9c2d9
		bounds[i].p1.x = (int)ceil ((r.p1.x + 1.0)*0.5*size.x) + 1;
Ivan Mahonin d9c2d9
		bounds[i].p1.y = (int)ceil ((r.p1.y + 1.0)*0.5*size.y) + 1;
Ivan Mahonin 8de121
	}
Ivan Mahonin 8de121
Ivan Mahonin f29469
	glGenBuffers(1, &buffer_id);
Ivan Mahonin f29469
	glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
Ivan Mahonin f29469
	glBufferData( GL_ARRAY_BUFFER,
Ivan Mahonin f29469
				  vertices.size()*sizeof(vec2f),
Ivan Mahonin f29469
				  &vertices.front(),
Ivan Mahonin f29469
				  GL_DYNAMIC_DRAW );
Ivan Mahonin 8de121
Ivan Mahonin f29469
	glGenVertexArrays(1, &array_id);
Ivan Mahonin f29469
	glBindVertexArray(array_id);
Ivan Mahonin 93cbac
Ivan Mahonin f29469
	glEnableVertexAttribArray(0);
Ivan Mahonin f29469
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_TRUE, 0, NULL);
Ivan Mahonin 6e407d
Ivan Mahonin f29469
	e.shaders.color(Color(0.f, 0.f, 1.f, 1.f));
Ivan Mahonin f29469
	glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
Ivan Mahonin f29469
	glFinish();
Ivan Mahonin f29469
	glClear(GL_COLOR_BUFFER_BIT);
Ivan Mahonin f29469
	glFinish();
Ivan Mahonin 93cbac
Ivan Mahonin 93cbac
	{
Ivan Mahonin f29469
		Measure t("render");
Ivan Mahonin f29469
		for(int i = 0; i < (int)data.size(); ++i) {
Ivan Mahonin f29469
			draw_contour(
Ivan Mahonin f29469
				e,
Ivan Mahonin f29469
				starts[i],
Ivan Mahonin f29469
				counts[i],
Ivan Mahonin d9c2d9
				bounds[i],
Ivan Mahonin f29469
				data[i].invert,
Ivan Mahonin f29469
				data[i].evenodd,
Ivan Mahonin f29469
				data[i].color );
Ivan Mahonin f29469
		}
Ivan Mahonin d9c2d9
		glFinish();
Ivan Mahonin 93cbac
	}
Ivan Mahonin 93cbac
}
Ivan Mahonin 93cbac
Ivan Mahonin f29469
void Test::test_sw(Environment &e, Data &data, Surface &surface) {
Ivan Mahonin f29469
	vector<Polyspan> polyspans(data.size());
Ivan Mahonin 93cbac
	{
Ivan Mahonin f29469
		Measure t("polyspans");
Ivan Mahonin f29469
		for(int i = 0; i < (int)data.size(); ++i) {
Ivan Mahonin f29469
			polyspans[i].init(0, 0, surface.width, surface.height);
Ivan Mahonin f29469
			data[i].contour.to_polyspan(polyspans[i]);
Ivan Mahonin f29469
			polyspans[i].sort_marks();
Ivan Mahonin f29469
		}
Ivan Mahonin 93cbac
	}
Ivan Mahonin 93cbac
Ivan Mahonin 93cbac
	{
Ivan Mahonin f29469
		Measure t("render");
Ivan Mahonin f29469
		for(int i = 0; i < (int)data.size(); ++i)
Ivan Mahonin f29469
			SwRender::polyspan(surface, polyspans[i], data[i].color, data[i].evenodd, data[i].invert);
Ivan Mahonin 93cbac
	}
Ivan Mahonin 93cbac
}
Ivan Mahonin 93cbac
Ivan Mahonin f29469
void Test::test_cl(Environment &e, Data &data, Surface &surface) {
Ivan Mahonin f29469
	vector<vec2f> paths;
Ivan Mahonin f29469
	vector<int> starts(data.size());
Ivan Mahonin f29469
	vector<int> counts(data.size());
Ivan Mahonin f29469
	for(int i = 0; i < (int)data.size(); ++i) {
Ivan Mahonin f29469
		starts[i] = paths.size();
Ivan Mahonin f29469
		for(Contour::ChunkList::const_iterator j = data[i].contour.get_chunks().begin(); j != data[i].contour.get_chunks().end(); ++j)
Ivan Mahonin f29469
			paths.push_back(vec2f(j->p1));
Ivan Mahonin f29469
		paths.push_back(paths[starts[i]]);
Ivan Mahonin f29469
		counts[i] = paths.size() - starts[i];
Ivan Mahonin 9edf2e
	}
Ivan Mahonin 9edf2e
Ivan Mahonin f29469
	ClRender clr(e.cl);
Ivan Mahonin f29469
	clr.send_surface(&surface);
Ivan Mahonin f29469
	clr.send_path(&paths.front(), paths.size());
Ivan Mahonin d989ab
Ivan Mahonin d989ab
	{
Ivan Mahonin f29469
		Measure t("render");
Ivan Mahonin f29469
		for(int i = 0; i < (int)data.size(); ++i)
Ivan Mahonin f29469
			clr.path(starts[i], counts[i], data[i].color, data[i].invert, data[i].evenodd);
Ivan Mahonin f29469
		clr.wait();
Ivan Mahonin c7fa36
	}
Ivan Mahonin c7fa36
Ivan Mahonin f29469
	clr.receive_surface();
Ivan Mahonin 9edf2e
}