|
|
93cbac |
/*
|
|
|
93cbac |
......... 2015 Ivan Mahonin
|
|
|
93cbac |
|
|
|
93cbac |
This program is free software: you can redistribute it and/or modify
|
|
|
93cbac |
it under the terms of the GNU General Public License as published by
|
|
|
93cbac |
the Free Software Foundation, either version 3 of the License, or
|
|
|
93cbac |
(at your option) any later version.
|
|
|
93cbac |
|
|
|
93cbac |
This program is distributed in the hope that it will be useful,
|
|
|
93cbac |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
93cbac |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
93cbac |
GNU General Public License for more details.
|
|
|
93cbac |
|
|
|
93cbac |
You should have received a copy of the GNU General Public License
|
|
|
93cbac |
along with this program. If not, see <http: licenses="" www.gnu.org="">.</http:>
|
|
|
93cbac |
*/
|
|
|
93cbac |
|
|
|
93cbac |
#include <fstream></fstream>
|
|
|
93cbac |
#include <iostream></iostream>
|
|
|
93cbac |
|
|
|
93cbac |
#include "test.h"
|
|
|
93cbac |
#include "contourbuilder.h"
|
|
|
8cd87e |
#include "triangulator.h"
|
|
|
49e693 |
#include "measure.h"
|
|
|
49e693 |
#include "utils.h"
|
|
|
d989ab |
#include "clrender.h"
|
|
|
93cbac |
|
|
|
93cbac |
|
|
|
93cbac |
using namespace std;
|
|
|
93cbac |
|
|
|
93cbac |
|
|
|
49e693 |
void Test::draw_contour(int start, int count, bool even_odd, bool invert, const Color &color) {
|
|
|
49e693 |
glEnable(GL_STENCIL_TEST);
|
|
|
93cbac |
|
|
|
49e693 |
// render mask
|
|
|
49e693 |
GLint draw_buffer;
|
|
|
49e693 |
glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
|
|
|
49e693 |
glDrawBuffer(GL_NONE);
|
|
|
49e693 |
glClear(GL_STENCIL_BUFFER_BIT);
|
|
|
49e693 |
glStencilFunc(GL_ALWAYS, 0, 0);
|
|
|
49e693 |
if (even_odd) {
|
|
|
49e693 |
glStencilOp(GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);
|
|
|
93cbac |
} else {
|
|
|
49e693 |
glStencilOpSeparate(GL_FRONT, GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);
|
|
|
49e693 |
glStencilOpSeparate(GL_BACK, GL_DECR_WRAP, GL_DECR_WRAP, GL_DECR_WRAP);
|
|
|
49e693 |
}
|
|
|
49e693 |
e.shaders.simple();
|
|
|
49e693 |
glDrawArrays(GL_TRIANGLE_STRIP, start, count);
|
|
|
49e693 |
glDrawBuffer((GLenum)draw_buffer);
|
|
|
49e693 |
|
|
|
49e693 |
// fill mask
|
|
|
49e693 |
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
|
|
49e693 |
if (!even_odd && !invert)
|
|
|
49e693 |
glStencilFunc(GL_NOTEQUAL, 0, -1);
|
|
|
49e693 |
if (!even_odd && invert)
|
|
|
49e693 |
glStencilFunc(GL_EQUAL, 0, -1);
|
|
|
49e693 |
if ( even_odd && !invert)
|
|
|
49e693 |
glStencilFunc(GL_EQUAL, 1, 1);
|
|
|
49e693 |
if ( even_odd && invert)
|
|
|
49e693 |
glStencilFunc(GL_EQUAL, 0, 1);
|
|
|
49e693 |
|
|
|
49e693 |
e.shaders.color(color);
|
|
|
49e693 |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
|
49e693 |
|
|
|
49e693 |
glDisable(GL_STENCIL_TEST);
|
|
|
7c6b57 |
}
|
|
|
7c6b57 |
|
|
|
9edf2e |
void Test::load(std::vector<contourinfo> &contours, const std::string &filename) {</contourinfo>
|
|
|
9edf2e |
vector<vector> groups;</vector>
|
|
|
9edf2e |
groups.push_back(Vector());
|
|
|
9edf2e |
|
|
|
9edf2e |
ifstream f("data/contours.txt");
|
|
|
9edf2e |
int vertices_count = 0;
|
|
|
9edf2e |
while(f) {
|
|
|
9edf2e |
string s;
|
|
|
9edf2e |
f >> s;
|
|
|
9edf2e |
if (s == "g") {
|
|
|
9edf2e |
Vector t;
|
|
|
9edf2e |
f >> t.x >> t.y;
|
|
|
9edf2e |
groups.push_back(groups.back() + t);
|
|
|
9edf2e |
} else
|
|
|
9edf2e |
if (s == "end") {
|
|
|
9edf2e |
groups.pop_back();
|
|
|
9edf2e |
if ((int)groups.size() == 1)
|
|
|
9edf2e |
break;
|
|
|
9edf2e |
} else
|
|
|
9edf2e |
if (s == "path") {
|
|
|
9edf2e |
contours.push_back(ContourInfo());
|
|
|
9edf2e |
ContourInfo &ci = contours.back();
|
|
|
9edf2e |
f >> ci.invert
|
|
|
9edf2e |
>> ci.antialias
|
|
|
9edf2e |
>> ci.evenodd
|
|
|
9edf2e |
>> ci.color.r
|
|
|
9edf2e |
>> ci.color.g
|
|
|
9edf2e |
>> ci.color.b
|
|
|
9edf2e |
>> ci.color.a;
|
|
|
9edf2e |
bool closed = true;
|
|
|
9edf2e |
while(true) {
|
|
|
9edf2e |
f >> s;
|
|
|
9edf2e |
Vector p1;
|
|
|
9edf2e |
if (s == "M") {
|
|
|
9edf2e |
f >> p1.x >> p1.y;
|
|
|
9edf2e |
ci.contour.move_to(p1 + groups.back());
|
|
|
9edf2e |
closed = false;
|
|
|
9edf2e |
} else
|
|
|
9edf2e |
if (s == "L") {
|
|
|
9edf2e |
f >> p1.x >> p1.y;
|
|
|
9edf2e |
if (closed) {
|
|
|
9edf2e |
ci.contour.move_to(p1 + groups.back());
|
|
|
9edf2e |
closed = false;
|
|
|
9edf2e |
}
|
|
|
9edf2e |
ci.contour.line_to(p1 + groups.back());
|
|
|
9edf2e |
} else
|
|
|
9edf2e |
if (s == "Z") {
|
|
|
9edf2e |
ci.contour.close();
|
|
|
9edf2e |
closed = true;
|
|
|
9edf2e |
} else
|
|
|
9edf2e |
if (s == "end") {
|
|
|
9edf2e |
break;
|
|
|
9edf2e |
} else {
|
|
|
9edf2e |
cout << "bug " << s << endl;
|
|
|
9edf2e |
if (!f) break;
|
|
|
9edf2e |
}
|
|
|
9edf2e |
}
|
|
|
9edf2e |
if (!closed)
|
|
|
9edf2e |
ci.contour.close();
|
|
|
9edf2e |
if (ci.color.a < 0.9999)
|
|
|
9edf2e |
contours.pop_back();
|
|
|
9edf2e |
else
|
|
|
9edf2e |
vertices_count += ci.contour.get_chunks().size();
|
|
|
9edf2e |
} else
|
|
|
9edf2e |
if (s != "") {
|
|
|
9edf2e |
cout << "bug " << s << endl;
|
|
|
9edf2e |
}
|
|
|
9edf2e |
}
|
|
|
9edf2e |
if ((int)groups.size() != 1)
|
|
|
9edf2e |
cout << "bug groups " << groups.size() << endl;
|
|
|
9edf2e |
|
|
|
9edf2e |
cout << contours.size() << " contours" << endl;
|
|
|
9edf2e |
cout << vertices_count << " vertices" << endl;
|
|
|
9edf2e |
}
|
|
|
9edf2e |
|
|
|
9edf2e |
|
|
|
93cbac |
void Test::test2() {
|
|
|
93cbac |
Contour c, cc;
|
|
|
93cbac |
ContourBuilder::build(cc);
|
|
|
93cbac |
cout << cc.get_chunks().size() << " commands" << endl;
|
|
|
93cbac |
|
|
|
49e693 |
Vector frame_size = Utils::get_frame_size();
|
|
|
831e90 |
|
|
|
93cbac |
Rect bounds;
|
|
|
93cbac |
bounds.p0 = Vector(-1.0, -1.0);
|
|
|
93cbac |
bounds.p1 = Vector( 1.0, 1.0);
|
|
|
831e90 |
Vector min_size(1.75/frame_size.x, 1.75/frame_size.y);
|
|
|
93cbac |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_2_split");
|
|
|
93cbac |
cc.split(c, bounds, min_size);
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
const Contour::ChunkList &chunks = c.get_chunks();
|
|
|
93cbac |
cout << chunks.size() << " vertices" << endl;
|
|
|
93cbac |
|
|
|
7c6b57 |
GLuint buffer_id = 0;
|
|
|
7c6b57 |
GLuint array_id = 0;
|
|
|
8de121 |
int count = 0;
|
|
|
a80036 |
vector< vec2<float> > vertices;</float>
|
|
|
8de121 |
|
|
|
8de121 |
{
|
|
|
49e693 |
Measure t("test_2_init_buffer");
|
|
|
7c6b57 |
vertices.resize(4+4*chunks.size());
|
|
|
7c6b57 |
glGenBuffers(1, &buffer_id);
|
|
|
7c6b57 |
glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
|
|
|
8de121 |
glBufferData( GL_ARRAY_BUFFER,
|
|
|
a80036 |
vertices.size()*sizeof(vec2<float>),</float>
|
|
|
8de121 |
&vertices.front(),
|
|
|
8de121 |
GL_DYNAMIC_DRAW );
|
|
|
8de121 |
vertices.clear();
|
|
|
7c6b57 |
vertices.reserve(4+4*chunks.size());
|
|
|
7c6b57 |
|
|
|
7c6b57 |
glGenVertexArrays(1, &array_id);
|
|
|
7c6b57 |
glBindVertexArray(array_id);
|
|
|
8de121 |
|
|
|
7c6b57 |
glEnableVertexAttribArray(0);
|
|
|
7c6b57 |
glVertexAttribPointer(0, 2, GL_FLOAT, GL_TRUE, 0, NULL);
|
|
|
7704aa |
|
|
|
49e693 |
e.shaders.color(Color(0.f, 0.f, 1.f, 1.f));
|
|
|
7c6b57 |
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
|
|
|
7c6b57 |
glFinish();
|
|
|
a80036 |
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
a80036 |
glFinish();
|
|
|
a80036 |
}
|
|
|
8de121 |
|
|
|
8de121 |
{
|
|
|
49e693 |
Measure t("test_2_prepare_data");
|
|
|
7c6b57 |
vertices.push_back(vec2<float>(bounds.p0.x, bounds.p0.y));</float>
|
|
|
7c6b57 |
vertices.push_back(vec2<float>(bounds.p0.x, bounds.p1.y));</float>
|
|
|
7c6b57 |
vertices.push_back(vec2<float>(bounds.p1.x, bounds.p0.y));</float>
|
|
|
7c6b57 |
vertices.push_back(vec2<float>(bounds.p1.x, bounds.p1.y));</float>
|
|
|
a80036 |
vertices.push_back(vec2<float>());</float>
|
|
|
a80036 |
vertices.push_back(vec2<float>());</float>
|
|
|
8de121 |
for(Contour::ChunkList::const_iterator i = chunks.begin(); i != chunks.end(); ++i) {
|
|
|
8de121 |
if ( i->type == Contour::LINE
|
|
|
8de121 |
|| i->type == Contour::CLOSE)
|
|
|
8de121 |
{
|
|
|
a80036 |
vertices.push_back(vec2<float>(i->p1));</float>
|
|
|
a80036 |
vertices.push_back(vec2<float>(-1.f, (float)i->p1.y));</float>
|
|
|
8de121 |
} else {
|
|
|
8de121 |
vertices.push_back(vertices.back());
|
|
|
a80036 |
vertices.push_back(vertices.back());
|
|
|
a80036 |
vertices.push_back(vec2<float>(i->p1));</float>
|
|
|
a80036 |
vertices.push_back(vertices.back());
|
|
|
8de121 |
}
|
|
|
8de121 |
}
|
|
|
7c6b57 |
count = vertices.size() - 4;
|
|
|
8de121 |
}
|
|
|
8de121 |
|
|
|
8de121 |
{
|
|
|
49e693 |
Measure t("test_2_send_data");
|
|
|
a80036 |
glBufferSubData( GL_ARRAY_BUFFER,
|
|
|
a80036 |
0,
|
|
|
7c6b57 |
vertices.size()*sizeof(vertices.front()),
|
|
|
a80036 |
&vertices.front() );
|
|
|
8de121 |
}
|
|
|
8de121 |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_2_simple_fill.tga");
|
|
|
7c6b57 |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
6e407d |
{
|
|
|
49e693 |
Measure t("test_2_array.tga");
|
|
|
7c6b57 |
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
|
7c6b57 |
glDrawArrays(GL_TRIANGLE_STRIP, 4, count);
|
|
|
7c6b57 |
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
|
6e407d |
}
|
|
|
6e407d |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_2_contour_fill.tga");
|
|
|
49e693 |
draw_contour(4, count, false, false, Color(0.f, 0.f, 1.f, 1.f));
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_2_contour_fill_invert.tga");
|
|
|
49e693 |
draw_contour(4, count, false, true, Color(0.f, 0.f, 1.f, 1.f));
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_2_contour_evenodd.tga");
|
|
|
49e693 |
draw_contour(4, count, true, false, Color(0.f, 0.f, 1.f, 1.f));
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_2_contour_evenodd_invert.tga");
|
|
|
49e693 |
draw_contour(4, count, true, true, Color(0.f, 0.f, 1.f, 1.f));
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
a80036 |
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
7c6b57 |
glDeleteBuffers(1, &buffer_id);
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
void Test::test3() {
|
|
|
93cbac |
Contour c;
|
|
|
93cbac |
ContourBuilder::build(c);
|
|
|
93cbac |
cout << c.get_chunks().size() << " commands" << endl;
|
|
|
93cbac |
|
|
|
49e693 |
Vector frame_size = Utils::get_frame_size();
|
|
|
831e90 |
int width = (int)frame_size.x;
|
|
|
831e90 |
int height = (int)frame_size.y;
|
|
|
831e90 |
|
|
|
93cbac |
Rect bounds;
|
|
|
93cbac |
bounds.p0 = Vector(-1.0, -1.0);
|
|
|
93cbac |
bounds.p1 = Vector( 1.0, 1.0);
|
|
|
93cbac |
Rect pixel_bounds;
|
|
|
831e90 |
pixel_bounds.p0 = Vector::zero();
|
|
|
831e90 |
pixel_bounds.p1 = frame_size;
|
|
|
93cbac |
|
|
|
93cbac |
c.transform(bounds, pixel_bounds);
|
|
|
93cbac |
|
|
|
93cbac |
Polyspan polyspan;
|
|
|
831e90 |
polyspan.init(0, 0, width, height);
|
|
|
93cbac |
|
|
|
831e90 |
Surface surface(width, height);
|
|
|
93cbac |
Color color(0.f, 0.f, 1.f, 1.f);
|
|
|
93cbac |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_3_build_polyspan");
|
|
|
93cbac |
c.to_polyspan(polyspan);
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
cout << polyspan.get_covers().size() << " covers" << endl;
|
|
|
93cbac |
|
|
|
93cbac |
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
|
93cbac |
glColor4d(0.0, 0.0, 1.0, 1.0);
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_3_polyspan_gl_lines.tga");
|
|
|
93cbac |
glBegin(GL_LINE_STRIP);
|
|
|
93cbac |
for(Polyspan::cover_array::const_iterator i = polyspan.get_covers().begin(); i != polyspan.get_covers().end(); ++i)
|
|
|
93cbac |
glVertex2d((double)i->x/1024.0*2.0 - 1.0, (double)i->y/1024.0*2.0 - 1.0);
|
|
|
93cbac |
glEnd();
|
|
|
93cbac |
}
|
|
|
93cbac |
glPopAttrib();
|
|
|
93cbac |
|
|
|
93cbac |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_3_polyspan_sort");
|
|
|
93cbac |
polyspan.sort_marks();
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_3_polyspan_fill.tga", surface);
|
|
|
572d9c |
SwRender::polyspan(surface, polyspan, color, false, false);
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_3_polyspan_fill_invert.tga", surface);
|
|
|
572d9c |
SwRender::polyspan(surface, polyspan, color, false, true);
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_3_polyspan_evenodd.tga", surface);
|
|
|
572d9c |
SwRender::polyspan(surface, polyspan, color, true, false);
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
{
|
|
|
49e693 |
Measure t("test_3_polyspan_evenodd_invert.tga", surface);
|
|
|
572d9c |
SwRender::polyspan(surface, polyspan, color, true, true);
|
|
|
93cbac |
}
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
9edf2e |
void Test::test4() {
|
|
|
49e693 |
Vector frame_size = Utils::get_frame_size();
|
|
|
9edf2e |
int width = (int)frame_size.x;
|
|
|
9edf2e |
int height = (int)frame_size.y;
|
|
|
9edf2e |
|
|
|
9edf2e |
Rect bounds_gl;
|
|
|
9edf2e |
bounds_gl.p0 = Vector(-1.0, -1.0);
|
|
|
9edf2e |
bounds_gl.p1 = Vector( 1.0, 1.0);
|
|
|
9edf2e |
|
|
|
9edf2e |
Rect bounds_sw;
|
|
|
9edf2e |
bounds_sw.p0 = Vector();
|
|
|
9edf2e |
bounds_sw.p1 = frame_size;
|
|
|
9edf2e |
|
|
|
9edf2e |
Rect bounds_file;
|
|
|
9edf2e |
bounds_file.p0 = Vector(0.0, 450.0);
|
|
|
9edf2e |
bounds_file.p1 = Vector(500.0, -50.0);
|
|
|
9edf2e |
|
|
|
9edf2e |
vector<contourinfo> contours;</contourinfo>
|
|
|
9edf2e |
load(contours, "contours.txt");
|
|
|
9edf2e |
|
|
|
9edf2e |
{
|
|
|
9edf2e |
// opengl
|
|
|
9edf2e |
|
|
|
9edf2e |
vector<contourinfo> contours_gl = contours;</contourinfo>
|
|
|
9edf2e |
int commands_count = 0;
|
|
|
9edf2e |
for(vector<contourinfo>::iterator i = contours_gl.begin(); i != contours_gl.end(); ++i) {</contourinfo>
|
|
|
9edf2e |
i->contour.transform(bounds_file, bounds_gl);
|
|
|
9edf2e |
commands_count += i->contour.get_chunks().size();
|
|
|
9edf2e |
}
|
|
|
9edf2e |
|
|
|
8cd87e |
// gl_stencil
|
|
|
8cd87e |
|
|
|
9edf2e |
GLuint buffer_id = 0;
|
|
|
9edf2e |
GLuint array_id = 0;
|
|
|
9edf2e |
vector< vec2<float> > vertices;</float>
|
|
|
9edf2e |
vector<int> starts(contours_gl.size());</int>
|
|
|
9edf2e |
vector<int> counts(contours_gl.size());</int>
|
|
|
9edf2e |
|
|
|
9edf2e |
{
|
|
|
49e693 |
Measure t("test_4_gl_init_buffer");
|
|
|
9edf2e |
vertices.resize(4 + 4*commands_count + 2*contours_gl.size());
|
|
|
9edf2e |
glGenBuffers(1, &buffer_id);
|
|
|
9edf2e |
glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
|
|
|
9edf2e |
glBufferData( GL_ARRAY_BUFFER,
|
|
|
9edf2e |
vertices.size()*sizeof(vec2<float>),</float>
|
|
|
9edf2e |
&vertices.front(),
|
|
|
9edf2e |
GL_DYNAMIC_DRAW );
|
|
|
9edf2e |
vertices.clear();
|
|
|
9edf2e |
vertices.reserve(4 + 4*commands_count);
|
|
|
9edf2e |
|
|
|
9edf2e |
glGenVertexArrays(1, &array_id);
|
|
|
9edf2e |
glBindVertexArray(array_id);
|
|
|
9edf2e |
|
|
|
9edf2e |
glEnableVertexAttribArray(0);
|
|
|
9edf2e |
glVertexAttribPointer(0, 2, GL_FLOAT, GL_TRUE, 0, NULL);
|
|
|
9edf2e |
|
|
|
49e693 |
e.shaders.color(Color(0.f, 0.f, 1.f, 1.f));
|
|
|
9edf2e |
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
|
|
|
9edf2e |
glFinish();
|
|
|
9edf2e |
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
9edf2e |
glFinish();
|
|
|
9edf2e |
}
|
|
|
9edf2e |
|
|
|
9edf2e |
{
|
|
|
49e693 |
Measure t("test_4_gl_stencil_prepare_data");
|
|
|
9edf2e |
vertices.push_back(vec2<float>(bounds_gl.p0.x, bounds_gl.p0.y));</float>
|
|
|
9edf2e |
vertices.push_back(vec2<float>(bounds_gl.p0.x, bounds_gl.p1.y));</float>
|
|
|
9edf2e |
vertices.push_back(vec2<float>(bounds_gl.p1.x, bounds_gl.p0.y));</float>
|
|
|
9edf2e |
vertices.push_back(vec2<float>(bounds_gl.p1.x, bounds_gl.p1.y));</float>
|
|
|
9edf2e |
for(int i = 0; i < (int)contours_gl.size(); ++i) {
|
|
|
9edf2e |
starts[i] = (int)vertices.size();
|
|
|
9edf2e |
const Contour::ChunkList &chunks = contours_gl[i].contour.get_chunks();
|
|
|
9edf2e |
for(Contour::ChunkList::const_iterator j = chunks.begin(); j != chunks.end(); ++j) {
|
|
|
9edf2e |
if (j->type == Contour::LINE) {
|
|
|
9edf2e |
vertices.push_back(vec2<float>(j->p1));</float>
|
|
|
9edf2e |
vertices.push_back(vec2<float>(-1.f, (float)j->p1.y));</float>
|
|
|
9edf2e |
} else
|
|
|
9edf2e |
if (j->type == Contour::CLOSE) {
|
|
|
9edf2e |
vertices.push_back(vec2<float>(j->p1));</float>
|
|
|
9edf2e |
vertices.push_back(vec2<float>(-1.f, (float)j->p1.y));</float>
|
|
|
9edf2e |
} else {
|
|
|
9edf2e |
vertices.push_back(vertices.back());
|
|
|
9edf2e |
vertices.push_back(vec2<float>(j->p1));</float>
|
|
|
9edf2e |
vertices.push_back(vertices.back());
|
|
|
9edf2e |
vertices.push_back(vec2<float>(-1.f, (float)j->p1.y));</float>
|
|
|
9edf2e |
}
|
|
|
9edf2e |
}
|
|
|
9edf2e |
counts[i] = (int)vertices.size() - starts[i];
|
|
|
9edf2e |
}
|
|
|
9edf2e |
}
|
|
|
9edf2e |
|
|
|
9edf2e |
{
|
|
|
49e693 |
Measure t("test_4_gl_stencil_send_data");
|
|
|
9edf2e |
glBufferSubData( GL_ARRAY_BUFFER,
|
|
|
9edf2e |
0,
|
|
|
9edf2e |
vertices.size()*sizeof(vertices.front()),
|
|
|
9edf2e |
&vertices.front() );
|
|
|
9edf2e |
}
|
|
|
9edf2e |
|
|
|
9edf2e |
{
|
|
|
49e693 |
Measure t("test_4_gl_stencil_points.tga");
|
|
|
8cd87e |
glDrawArrays(GL_POINTS, 0, vertices.size());
|
|
|
8cd87e |
}
|
|
|
8cd87e |
|
|
|
8cd87e |
{
|
|
|
49e693 |
Measure t("test_4_gl_stencil_render.tga");
|
|
|
9edf2e |
for(int i = 0; i < (int)contours_gl.size(); ++i) {
|
|
|
49e693 |
draw_contour(
|
|
|
9edf2e |
starts[i],
|
|
|
9edf2e |
counts[i],
|
|
|
9edf2e |
contours_gl[i].invert,
|
|
|
9edf2e |
contours_gl[i].evenodd,
|
|
|
9edf2e |
contours_gl[i].color );
|
|
|
9edf2e |
}
|
|
|
9edf2e |
// glDrawArrays(GL_POINTS, 0, vertices.size());
|
|
|
9edf2e |
}
|
|
|
8cd87e |
|
|
|
8cd87e |
// gl_triangles
|
|
|
8cd87e |
|
|
|
8cd87e |
GLuint index_buffer_id = 0;
|
|
|
8cd87e |
vector<int> triangle_starts(contours_gl.size());</int>
|
|
|
8cd87e |
vector<int> triangle_counts(contours_gl.size());</int>
|
|
|
8cd87e |
vector<int> triangles;</int>
|
|
|
8cd87e |
vertices.clear();
|
|
|
8cd87e |
vertices.reserve(commands_count);
|
|
|
8cd87e |
|
|
|
8cd87e |
{
|
|
|
49e693 |
Measure t("test_4_gl_init_index_buffer");
|
|
|
8cd87e |
triangles.resize(3*commands_count);
|
|
|
8cd87e |
glGenBuffers(1, &index_buffer_id);
|
|
|
8cd87e |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id);
|
|
|
8cd87e |
glBufferData( GL_ELEMENT_ARRAY_BUFFER,
|
|
|
8cd87e |
triangles.size()*sizeof(triangles.front()),
|
|
|
8cd87e |
&triangles.front(),
|
|
|
8cd87e |
GL_DYNAMIC_DRAW );
|
|
|
8cd87e |
triangles.clear();
|
|
|
8cd87e |
triangles.reserve(3*commands_count);
|
|
|
8cd87e |
}
|
|
|
8cd87e |
|
|
|
8cd87e |
{
|
|
|
49e693 |
Measure t("test_4_gl_triangulate");
|
|
|
8cd87e |
int index_offset = 4;
|
|
|
8cd87e |
for(int i = 0; i < (int)contours_gl.size(); ++i) {
|
|
|
8cd87e |
triangle_starts[i] = (int)triangles.size();
|
|
|
8cd87e |
Triangulator::triangulate(contours_gl[i].contour, triangles, index_offset);
|
|
|
8cd87e |
triangle_counts[i] = (int)triangles.size() - triangle_starts[i];
|
|
|
8cd87e |
index_offset += (int)contours_gl[i].contour.get_chunks().size();
|
|
|
8cd87e |
}
|
|
|
8cd87e |
}
|
|
|
8cd87e |
|
|
|
8cd87e |
cout << triangles.size() << " triangles" << endl;
|
|
|
8cd87e |
|
|
|
8cd87e |
{
|
|
|
49e693 |
Measure t("test_4_gl_triangles_prepare_vertices");
|
|
|
8cd87e |
for(int i = 0; i < (int)contours_gl.size(); ++i) {
|
|
|
8cd87e |
const Contour::ChunkList &chunks = contours_gl[i].contour.get_chunks();
|
|
|
8cd87e |
for(Contour::ChunkList::const_iterator j = chunks.begin(); j != chunks.end(); ++j)
|
|
|
8cd87e |
vertices.push_back(vec2<float>(j->p1));</float>
|
|
|
8cd87e |
}
|
|
|
8cd87e |
}
|
|
|
8cd87e |
|
|
|
8cd87e |
{
|
|
|
49e693 |
Measure t("test_4_gl_triangles_send_data");
|
|
|
8cd87e |
glBufferSubData( GL_ARRAY_BUFFER,
|
|
|
8cd87e |
4*sizeof(vertices.front()),
|
|
|
8cd87e |
vertices.size()*sizeof(vertices.front()),
|
|
|
8cd87e |
&vertices.front() );
|
|
|
8cd87e |
glBufferSubData( GL_ELEMENT_ARRAY_BUFFER,
|
|
|
8cd87e |
0,
|
|
|
8cd87e |
triangles.size()*sizeof(triangles.front()),
|
|
|
8cd87e |
&triangles.front() );
|
|
|
8cd87e |
}
|
|
|
8cd87e |
|
|
|
8cd87e |
{
|
|
|
49e693 |
Measure t("test_4_gl_triangles_render.tga");
|
|
|
8cd87e |
for(int i = 0; i < (int)contours_gl.size(); ++i) {
|
|
|
49e693 |
e.shaders.color(contours_gl[i].color);
|
|
|
8cd87e |
glDrawElements(GL_TRIANGLES, triangle_counts[i], GL_UNSIGNED_INT, (char*)NULL + triangle_starts[i]*sizeof(int));
|
|
|
8cd87e |
}
|
|
|
8cd87e |
}
|
|
|
9edf2e |
}
|
|
|
9edf2e |
|
|
|
9edf2e |
{
|
|
|
9edf2e |
// software
|
|
|
9edf2e |
|
|
|
9edf2e |
vector<contourinfo> contours_sw = contours;</contourinfo>
|
|
|
9edf2e |
for(vector<contourinfo>::iterator i = contours_sw.begin(); i != contours_sw.end(); ++i)</contourinfo>
|
|
|
9edf2e |
i->contour.transform(bounds_file, bounds_sw);
|
|
|
9edf2e |
|
|
|
9edf2e |
vector<polyspan> polyspans(contours_sw.size());</polyspan>
|
|
|
9edf2e |
{
|
|
|
49e693 |
Measure t("test_4_sw_build_polyspans");
|
|
|
9edf2e |
for(int i = 0; i < (int)contours_sw.size(); ++i) {
|
|
|
9edf2e |
polyspans[i].init(0, 0, width, height);
|
|
|
9edf2e |
contours_sw[i].contour.to_polyspan(polyspans[i]);
|
|
|
9edf2e |
polyspans[i].sort_marks();
|
|
|
9edf2e |
}
|
|
|
9edf2e |
}
|
|
|
9edf2e |
|
|
|
9edf2e |
Surface surface(width, height);
|
|
|
9edf2e |
|
|
|
9edf2e |
{
|
|
|
49e693 |
Measure t("test_4_sw_render_polyspans.tga", surface);
|
|
|
9edf2e |
for(int i = 0; i < (int)contours_sw.size(); ++i)
|
|
|
572d9c |
SwRender::polyspan(surface, polyspans[i], contours_sw[i].color, contours_sw[i].evenodd, contours_sw[i].invert);
|
|
|
9edf2e |
}
|
|
|
9edf2e |
}
|
|
|
d989ab |
|
|
|
d989ab |
{
|
|
|
d989ab |
// cl
|
|
|
d989ab |
|
|
|
d989ab |
vector<contourinfo> contours_cl = contours;</contourinfo>
|
|
|
d989ab |
Surface surface(width+2, height+2);
|
|
|
d989ab |
|
|
|
d989ab |
Measure t("test_4_cl.tga", surface);
|
|
|
d989ab |
|
|
|
d989ab |
ClRender clr(e.cl);
|
|
|
d989ab |
clr.send_surface(&surface);
|
|
|
d989ab |
for(vector<contourinfo>::const_iterator i = contours_cl.begin(); i != contours_cl.end(); ++i)</contourinfo>
|
|
|
d989ab |
clr.contour(i->contour, bounds_file, i->color, i->invert, i->evenodd);
|
|
|
d989ab |
clr.receive_surface();
|
|
|
d989ab |
}
|
|
|
9edf2e |
}
|