diff --git a/c++/contourgl/contourgl.cpp b/c++/contourgl/contourgl.cpp index 14d1b0a..9da6579 100644 --- a/c++/contourgl/contourgl.cpp +++ b/c++/contourgl/contourgl.cpp @@ -15,13 +15,11 @@ along with this program. If not, see . */ -#include +#include #include -#include #include -#include -#include +#include #include #include @@ -38,6 +36,10 @@ typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display*, GLXFBConfig, GLXC using namespace std; +clock_t get_clock() { + return clock(); +} + int main() { // open display (we will use default display and screen 0) Display *display = XOpenDisplay(NULL); diff --git a/c++/contourgl/geometry.h b/c++/contourgl/geometry.h index 10f6ad8..50f6d0c 100644 --- a/c++/contourgl/geometry.h +++ b/c++/contourgl/geometry.h @@ -46,42 +46,51 @@ inline bool angle_between(Real a0, Real a1, Real a, Real round) { return a0 < a && a < a1; } -class Vector { +template +class vec2 { public: + typedef T type; + union { - struct { Real x, y; }; - struct { Real coords[]; }; + struct { type x, y; }; + struct { type coords[]; }; }; - Vector(): + vec2(): x(), y() { } - Vector(Real x, Real y): + vec2(type x, type y): x(x), y(y) { } - Real& operator[] (int index) + template + explicit vec2(const vec2 &other): + x((type)other.x), y((type)other.y) { } + + type& operator[] (int index) { return coords[index]; } - const Real& operator[] (int index) const + const type& operator[] (int index) const { return coords[index]; } - bool is_equal_to(const Vector &other) const + bool is_equal_to(const vec2 &other) const { return fabs(x - other.x) < 1e-6 && fabs(y - other.y) < 1e-6; } - Vector operator+(const Vector &a) const - { return Vector(x + a.x, y + a.y); } - Vector operator-(const Vector &a) const - { return Vector(x - a.x, y - a.y); } - Vector operator*(const Vector &a) const - { return Vector(x*a.x, y*a.y); } - Vector operator/(const Vector &a) const - { return Vector(x/a.x, y/a.y); } - - Vector operator*(Real a) const - { return Vector(x*a, y*a); } - Vector operator/(Real a) const - { return Vector(x/a, y/a); } - - static Vector zero() { return Vector(); } + vec2 operator+(const vec2 &a) const + { return vec2(x + a.x, y + a.y); } + vec2 operator-(const vec2 &a) const + { return vec2(x - a.x, y - a.y); } + vec2 operator*(const vec2 &a) const + { return vec2(x*a.x, y*a.y); } + vec2 operator/(const vec2 &a) const + { return vec2(x/a.x, y/a.y); } + + vec2 operator*(type a) const + { return vec2(x*a, y*a); } + vec2 operator/(type a) const + { return vec2(x/a, y/a); } + + static vec2 zero() { return vec2(); } }; +typedef vec2 Vector; + class Rect { public: Vector p0, p1; diff --git a/c++/contourgl/test.cpp b/c++/contourgl/test.cpp index 5736425..dcb60c7 100644 --- a/c++/contourgl/test.cpp +++ b/c++/contourgl/test.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -174,10 +175,15 @@ public: } }; +Test::Wrapper::Wrapper(const std::string &filename): + filename(filename), surface(), t(get_clock()) +{ } + Test::Wrapper::~Wrapper() { if (!surface) glFinish(); - Real ms = 1000.0*(Real)(clock() - t)/(Real)(CLOCKS_PER_SEC); - cout << ms << " ms - " << filename << endl; + Real ms = 1000.0*(Real)(get_clock() - t)/(Real)(CLOCKS_PER_SEC); + cout << setw(8) << fixed << setprecision(3) + << ms << " ms - " << filename << endl; if (filename.size() > 4 && filename.substr(filename.size()-4, 4) == ".tga") { if (surface) @@ -241,7 +247,7 @@ void Test::test2() { Rect bounds; bounds.p0 = Vector(-1.0, -1.0); bounds.p1 = Vector( 1.0, 1.0); - Vector min_size(1.0/1024.0, 1.0/1024.0); + Vector min_size(1.75/1024.0, 1.75/1024.0); { Wrapper("test_2_split"); @@ -256,7 +262,7 @@ void Test::test2() { GLuint buf_id = 0; int count = 0; - vector vertices; + vector< vec2 > vertices; { Wrapper t("test_2_init_buffer"); @@ -264,26 +270,33 @@ void Test::test2() { glGenBuffers(1, &buf_id); glBindBuffer(GL_ARRAY_BUFFER, buf_id); glBufferData( GL_ARRAY_BUFFER, - vertices.size()*sizeof(Vector), + vertices.size()*sizeof(vec2), &vertices.front(), GL_DYNAMIC_DRAW ); vertices.clear(); - } + vertices.reserve(4*chunks.size()); + glEnableClientState(GL_VERTEX_ARRAY); + glDrawArrays(GL_TRIANGLES, 0, vertices.size()); + glClear(GL_COLOR_BUFFER_BIT); + glFinish(); + } { Wrapper t("test_2_prepare_data"); + vertices.push_back(vec2()); + vertices.push_back(vec2()); for(Contour::ChunkList::const_iterator i = chunks.begin(); i != chunks.end(); ++i) { if ( i->type == Contour::LINE || i->type == Contour::CLOSE) { - vertices.push_back(i->p1); - vertices.push_back(Vector(-1.0, i->p1.y)); + vertices.push_back(vec2(i->p1)); + vertices.push_back(vec2(-1.f, (float)i->p1.y)); } else { - vertices.push_back(vertices.empty() ? Vector() : vertices.back()); vertices.push_back(vertices.back()); - vertices.push_back(i->p1); - vertices.push_back(i->p1); + vertices.push_back(vertices.back()); + vertices.push_back(vec2(i->p1)); + vertices.push_back(vertices.back()); } } count = vertices.size(); @@ -291,11 +304,11 @@ void Test::test2() { { Wrapper t("test_2_send_data"); - glBufferData( GL_ARRAY_BUFFER, - vertices.size()*sizeof(Vector), - &vertices.front(), - GL_DYNAMIC_DRAW ); - glVertexPointer(2, GL_FLOAT, sizeof(Vector), 0); + glBufferSubData( GL_ARRAY_BUFFER, + 0, + vertices.size()*sizeof(vec2), + &vertices.front() ); + glVertexPointer(2, GL_FLOAT, sizeof(vec2), 0); } { @@ -326,6 +339,8 @@ void Test::test2() { Helper::draw_contour(count, true, true); } + glDisableClientState(GL_VERTEX_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &buf_id); glPopAttrib(); } diff --git a/c++/contourgl/test.h b/c++/contourgl/test.h index dd0066a..f35f57a 100644 --- a/c++/contourgl/test.h +++ b/c++/contourgl/test.h @@ -23,6 +23,8 @@ class Surface; +clock_t get_clock(); + class Test { public: class Wrapper { @@ -34,7 +36,7 @@ public: Wrapper(const Wrapper&): surface(), t() { } Wrapper& operator= (const Wrapper&) { return *this; } public: - Wrapper(const std::string &filename): filename(filename), surface(), t(clock()) { } + Wrapper(const std::string &filename); Wrapper(const std::string &filename, Surface &surface): filename(filename), surface(&surface), t(clock()) { } ~Wrapper(); };