diff --git a/c++/contourgl/Makefile b/c++/contourgl/Makefile
index 9a6d776..dfe2f43 100644
--- a/c++/contourgl/Makefile
+++ b/c++/contourgl/Makefile
@@ -1,9 +1,55 @@
DEPLIBS = gl x11 OpenCL
CXXFLAGS = -O0 -g -Wall -fmessage-length=0 `pkg-config --cflags $(DEPLIBS)` -DGL_GLEXT_PROTOTYPES
-DEPS = clcontext.h contour.h contourgl.h contourbuilder.h geometry.h polyspan.h rendersw.h shaders.h test.h triangulator.h \
- clcontext.cpp contour.cpp contourgl.cpp contourbuilder.cpp polyspan.cpp rendersw.cpp shaders.cpp test.cpp triangulator.cpp
-OBJS = clcontext.o contour.o contourgl.o contourbuilder.o polyspan.o rendersw.o shaders.o test.o triangulator.o
+
+HEADERS = \
+ clcontext.h \
+ contour.h \
+ contourbuilder.h \
+ environment.h \
+ geometry.h \
+ glcontext.h \
+ measure.h \
+ polyspan.h \
+ rendersw.h \
+ shaders.h \
+ test.h \
+ triangulator.h \
+ utils.h
+
+SOURCES = \
+ contourgl.cpp \
+ clcontext.cpp \
+ contour.cpp \
+ contourbuilder.cpp \
+ environment.cpp \
+ geometry.cpp \
+ glcontext.cpp \
+ measure.cpp \
+ polyspan.cpp \
+ rendersw.cpp \
+ shaders.cpp \
+ test.cpp \
+ triangulator.cpp \
+ utils.cpp
+
+OBJS = \
+ contourgl.o \
+ clcontext.o \
+ contour.o \
+ contourbuilder.o \
+ environment.o \
+ geometry.o \
+ glcontext.o \
+ measure.o \
+ polyspan.o \
+ rendersw.o \
+ shaders.o \
+ test.o \
+ triangulator.o \
+ utils.o
+
+DEPS = $(HEADERS) $(SOURCES)
LIBS = `pkg-config --libs $(DEPLIBS)`
TARGET = contourgl
diff --git a/c++/contourgl/clcontext.h b/c++/contourgl/clcontext.h
index 57fe157..2114f9a 100644
--- a/c++/contourgl/clcontext.h
+++ b/c++/contourgl/clcontext.h
@@ -15,6 +15,9 @@
along with this program. If not, see .
*/
+#ifndef _CLCONTEXT_H_
+#define _CLCONTEXT_H_
+
#include
#include
@@ -31,3 +34,5 @@ public:
void hello();
};
+
+#endif
diff --git a/c++/contourgl/contourgl.cpp b/c++/contourgl/contourgl.cpp
index 3e8655f..b1a2546 100644
--- a/c++/contourgl/contourgl.cpp
+++ b/c++/contourgl/contourgl.cpp
@@ -15,168 +15,22 @@
along with this program. If not, see .
*/
-#include
-#include
-
#include
-#include
-
-#include
-#include
-#include
-#include "clcontext.h"
#include "test.h"
-#include "shaders.h"
-
-
-#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
-typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
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);
- assert(display);
-
- // choose config
- int config_attribs[] = {
- GLX_DOUBLEBUFFER, False,
- GLX_RED_SIZE, 8,
- GLX_GREEN_SIZE, 8,
- GLX_BLUE_SIZE, 8,
- GLX_ALPHA_SIZE, 8,
- GLX_DEPTH_SIZE, 24,
- GLX_STENCIL_SIZE, 8,
- GLX_ACCUM_RED_SIZE, 8,
- GLX_ACCUM_GREEN_SIZE, 8,
- GLX_ACCUM_BLUE_SIZE, 8,
- GLX_ACCUM_ALPHA_SIZE, 8,
- GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
- None };
- int nelements = 0;
- GLXFBConfig *configs = glXChooseFBConfig(display, 0, config_attribs, &nelements);
- assert(configs != NULL && nelements > 0);
- GLXFBConfig config = configs[0];
- assert(config);
-
- // create pbuffer
- int pbuffer_width = 256;
- int pbuffer_height = 256;
- int pbuffer_attribs[] = {
- GLX_PBUFFER_WIDTH, pbuffer_width,
- GLX_PBUFFER_HEIGHT, pbuffer_height,
- None };
- GLXPbuffer pbuffer = glXCreatePbuffer(display, config, pbuffer_attribs);
- assert(pbuffer);
-
- // create context
- int context_attribs[] = {
- GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
- GLX_CONTEXT_MINOR_VERSION_ARB, 3,
- None };
- GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
- GLXContext context = glXCreateContextAttribsARB(display, config, NULL, True, context_attribs);
- assert(context);
-
- // make context current
- glXMakeContextCurrent(display, pbuffer, pbuffer, context);
-
- // frame buffer
- int framebuffer_width = 512;
- int framebuffer_height = 512;
- int framebuffer_samples = 16;
- bool antialising = false;
- bool hdr = false;
-
- GLenum internal_format = hdr ? GL_RGBA16F : GL_RGBA;
- GLenum color_type = hdr ? GL_FLOAT : GL_UNSIGNED_BYTE;
-
- GLuint multisample_texture_id = 0;
- glGenTextures(1, &multisample_texture_id);
- glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, multisample_texture_id);
- glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, framebuffer_samples, internal_format, framebuffer_width, framebuffer_height, GL_TRUE);
-
- GLuint multisample_renderbuffer_id = 0;
- glGenRenderbuffers(1, &multisample_renderbuffer_id);
- glBindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer_id);
- glRenderbufferStorageMultisample(GL_RENDERBUFFER, framebuffer_samples, GL_STENCIL_INDEX8, framebuffer_width, framebuffer_height);
-
- GLuint multisample_framebuffer_id = 0;
- glGenFramebuffers(1, &multisample_framebuffer_id);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, multisample_framebuffer_id);
- glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, multisample_renderbuffer_id);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, multisample_texture_id, 0);
-
- GLuint texture_id = 0;
- glGenTextures(1, &texture_id);
- glBindTexture(GL_TEXTURE_2D, texture_id);
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, framebuffer_width, framebuffer_height, 0, GL_RGBA, color_type, NULL);
-
- GLuint renderbuffer_id = 0;
- glGenRenderbuffers(1, &renderbuffer_id);
- glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_id);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, framebuffer_width, framebuffer_height);
-
- GLuint framebuffer_id = 0;
- glGenFramebuffers(1, &framebuffer_id);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer_id);
- glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuffer_id);
- glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
-
- cout << "Framebuffer status:" << setbase(16)
- << " 0x" << glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
- << " 0x" << glCheckFramebufferStatus(GL_READ_FRAMEBUFFER)
- << setbase(10) << endl;
-
- // set view port
- glViewport(0, 0, framebuffer_width, framebuffer_height);
-
- if (antialising)
- glEnable(GL_MULTISAMPLE);
- else
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_id);
-
- Shaders::initialize();
-
- // do something
- //Test::test1();
- //Test::test2();
- //Test::test3();
- //Test::test4();
-
- ClContext().hello();
-
- Shaders::deinitialize();
-
- // deinitialization
- glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
- glDeleteFramebuffers(1, &framebuffer_id);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glDeleteTextures(1, &texture_id);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
- glDeleteFramebuffers(1, &multisample_framebuffer_id);
-
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
- glDeleteRenderbuffers(1, &multisample_renderbuffer_id);
-
- glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
- glDeleteTextures(1, &multisample_texture_id);
+ Environment e;
+ Test test(e);
- glXMakeContextCurrent(display, None, None, NULL);
- glXDestroyContext(display, context);
- glXDestroyPbuffer(display, pbuffer);
- XCloseDisplay(display);
+ e.cl.hello();
+ test.test2();
+ test.test3();
+ test.test4();
cout << "done" << endl;
return 0;
diff --git a/c++/contourgl/environment.cpp b/c++/contourgl/environment.cpp
new file mode 100644
index 0000000..068019c
--- /dev/null
+++ b/c++/contourgl/environment.cpp
@@ -0,0 +1,18 @@
+/*
+ ......... 2015 Ivan Mahonin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "environment.h"
diff --git a/c++/contourgl/environment.h b/c++/contourgl/environment.h
new file mode 100644
index 0000000..49c0cb5
--- /dev/null
+++ b/c++/contourgl/environment.h
@@ -0,0 +1,32 @@
+/*
+ ......... 2015 Ivan Mahonin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef _ENVIRONMENT_H_
+#define _ENVIRONMENT_H_
+
+#include "glcontext.h"
+#include "clcontext.h"
+#include "shaders.h"
+
+class Environment {
+public:
+ GlContext gl;
+ ClContext cl;
+ Shaders shaders;
+};
+
+#endif
diff --git a/c++/contourgl/geometry.cpp b/c++/contourgl/geometry.cpp
new file mode 100644
index 0000000..8d9a1e8
--- /dev/null
+++ b/c++/contourgl/geometry.cpp
@@ -0,0 +1,18 @@
+/*
+ ......... 2015 Ivan Mahonin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "geometry.h"
diff --git a/c++/contourgl/glcontext.cpp b/c++/contourgl/glcontext.cpp
new file mode 100644
index 0000000..06cfcca
--- /dev/null
+++ b/c++/contourgl/glcontext.cpp
@@ -0,0 +1,175 @@
+/*
+ ......... 2015 Ivan Mahonin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+
+#include
+#include
+
+#include "glcontext.h"
+
+
+using namespace std;
+
+
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+
+
+GlContext::GlContext():
+ display(),
+ pbuffer(),
+ context(),
+ texture_id(),
+ framebuffer_id(),
+ renderbuffer_id(),
+ multisample_texture_id(),
+ multisample_renderbuffer_id(),
+ multisample_framebuffer_id()
+{
+
+ // options
+
+ int framebuffer_width = 512;
+ int framebuffer_height = 512;
+ int framebuffer_samples = 16;
+ bool antialising = false;
+ bool hdr = false;
+
+ // display
+
+ display = XOpenDisplay(NULL);
+ assert(display);
+
+ // config
+
+ int config_attribs[] = {
+ GLX_DOUBLEBUFFER, False,
+ GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8,
+ GLX_ALPHA_SIZE, 8,
+ GLX_DEPTH_SIZE, 24,
+ GLX_STENCIL_SIZE, 8,
+ GLX_ACCUM_RED_SIZE, 8,
+ GLX_ACCUM_GREEN_SIZE, 8,
+ GLX_ACCUM_BLUE_SIZE, 8,
+ GLX_ACCUM_ALPHA_SIZE, 8,
+ GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
+ None };
+ int nelements = 0;
+ GLXFBConfig *configs = glXChooseFBConfig(display, 0, config_attribs, &nelements);
+ assert(configs != NULL && nelements > 0);
+ GLXFBConfig config = configs[0];
+ assert(config);
+
+ // pbuffer
+
+ int pbuffer_width = 256;
+ int pbuffer_height = 256;
+ int pbuffer_attribs[] = {
+ GLX_PBUFFER_WIDTH, pbuffer_width,
+ GLX_PBUFFER_HEIGHT, pbuffer_height,
+ None };
+ pbuffer = glXCreatePbuffer(display, config, pbuffer_attribs);
+ assert(pbuffer);
+
+ // context
+
+ int context_attribs[] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 3,
+ None };
+ GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
+ context = glXCreateContextAttribsARB(display, config, NULL, True, context_attribs);
+ assert(context);
+
+ glXMakeContextCurrent(display, pbuffer, pbuffer, context);
+
+ // frame buffer
+
+ GLenum internal_format = hdr ? GL_RGBA16F : GL_RGBA;
+ GLenum color_type = hdr ? GL_FLOAT : GL_UNSIGNED_BYTE;
+
+ glGenTextures(1, &texture_id);
+ glBindTexture(GL_TEXTURE_2D, texture_id);
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, framebuffer_width, framebuffer_height, 0, GL_RGBA, color_type, NULL);
+
+ glGenRenderbuffers(1, &renderbuffer_id);
+ glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_id);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, framebuffer_width, framebuffer_height);
+
+ glGenFramebuffers(1, &framebuffer_id);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer_id);
+ glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuffer_id);
+ glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
+
+ glGenTextures(1, &multisample_texture_id);
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, multisample_texture_id);
+ glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, framebuffer_samples, internal_format, framebuffer_width, framebuffer_height, GL_TRUE);
+
+ glGenRenderbuffers(1, &multisample_renderbuffer_id);
+ glBindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer_id);
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, framebuffer_samples, GL_STENCIL_INDEX8, framebuffer_width, framebuffer_height);
+
+ glGenFramebuffers(1, &multisample_framebuffer_id);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, multisample_framebuffer_id);
+ glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, multisample_renderbuffer_id);
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, multisample_texture_id, 0);
+
+ cout << "Framebuffer status:" << setbase(16)
+ << " 0x" << glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
+ << " 0x" << glCheckFramebufferStatus(GL_READ_FRAMEBUFFER)
+ << setbase(10) << endl;
+
+ if (antialising)
+ glEnable(GL_MULTISAMPLE);
+ else
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_id);
+
+ // view port
+
+ glViewport(0, 0, framebuffer_width, framebuffer_height);
+}
+
+GlContext::~GlContext() {
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glDeleteFramebuffers(1, &framebuffer_id);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &texture_id);
+
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ glDeleteFramebuffers(1, &multisample_framebuffer_id);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ glDeleteRenderbuffers(1, &multisample_renderbuffer_id);
+
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
+ glDeleteTextures(1, &multisample_texture_id);
+
+ glXMakeContextCurrent(display, None, None, NULL);
+ glXDestroyContext(display, context);
+ glXDestroyPbuffer(display, pbuffer);
+ XCloseDisplay(display);
+}
+
+void GlContext::check(const std::string &s) {
+ if (GLenum error = glGetError())
+ cout << s << " GL error: 0x" << setbase(16) << error << setbase(10) << endl;
+}
diff --git a/c++/contourgl/glcontext.h b/c++/contourgl/glcontext.h
new file mode 100644
index 0000000..6fc8597
--- /dev/null
+++ b/c++/contourgl/glcontext.h
@@ -0,0 +1,48 @@
+/*
+ ......... 2015 Ivan Mahonin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef _GLCONTEXT_H_
+#define _GLCONTEXT_H_
+
+#include
+
+#include
+#include
+#include
+
+
+class GlContext {
+public:
+ Display *display;
+ GLXPbuffer pbuffer;
+ GLXContext context;
+
+ GLuint texture_id;
+ GLuint framebuffer_id;
+ GLuint renderbuffer_id;
+
+ GLuint multisample_texture_id;
+ GLuint multisample_renderbuffer_id;
+ GLuint multisample_framebuffer_id;
+
+ GlContext();
+ ~GlContext();
+
+ void check(const std::string &s = std::string());
+};
+
+#endif
diff --git a/c++/contourgl/measure.cpp b/c++/contourgl/measure.cpp
new file mode 100644
index 0000000..b57a5c8
--- /dev/null
+++ b/c++/contourgl/measure.cpp
@@ -0,0 +1,79 @@
+/*
+ ......... 2015 Ivan Mahonin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+#include
+
+#include "measure.h"
+#include "utils.h"
+#include "glcontext.h"
+
+
+using namespace std;
+
+
+std::vector Measure::stack;
+
+
+Measure::Measure(const std::string &filename):
+ filename(filename),
+ surface(),
+ tga(filename.size() > 4 && filename.substr(filename.size()-4, 4) == ".tga"),
+ sub_tasks(),
+ t()
+{
+ stack.push_back(this);
+ t = clock();
+}
+
+Measure::Measure(const std::string &filename, Surface &surface):
+ filename(filename),
+ surface(&surface),
+ tga(filename.size() > 4 && filename.substr(filename.size()-4, 4) == ".tga"),
+ sub_tasks(),
+ t()
+{
+ stack.push_back(this);
+ t = clock();
+}
+
+Measure::~Measure() {
+ if (!surface && tga) glFinish();
+
+ clock_t dt = sub_tasks ? sub_tasks : clock() - t;
+ Real ms = 1000.0*(Real)(clock() - t)/(Real)(CLOCKS_PER_SEC);
+ cout << setw(8) << fixed << setprecision(3)
+ << ms << " ms - " << filename << flush << endl;
+
+ if (tga) {
+ if (surface)
+ Utils::save_surface(*surface, filename);
+ else
+ Utils::save_viewport(filename);
+ }
+
+ if (surface) {
+ surface->clear();
+ } else {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glFinish();
+ }
+
+ stack.pop_back();
+ if (!stack.empty()) stack.back()->sub_tasks += dt;
+}
+
diff --git a/c++/contourgl/measure.h b/c++/contourgl/measure.h
new file mode 100644
index 0000000..c8ff69a
--- /dev/null
+++ b/c++/contourgl/measure.h
@@ -0,0 +1,46 @@
+/*
+ ......... 2015 Ivan Mahonin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef _MEASURE_H_
+#define _MEASURE_H_
+
+#include
+
+#include
+#include
+
+#include "rendersw.h"
+
+
+class Measure {
+private:
+ static std::vector stack;
+ std::string filename;
+ Surface *surface;
+ bool tga;
+ clock_t sub_tasks;
+ clock_t t;
+
+ Measure(const Measure&): surface(), tga(), sub_tasks(), t() { }
+ Measure& operator= (const Measure&) { return *this; }
+public:
+ Measure(const std::string &filename);
+ Measure(const std::string &filename, Surface &surface);
+ ~Measure();
+};
+
+#endif
diff --git a/c++/contourgl/shaders.cpp b/c++/contourgl/shaders.cpp
index 87d34cc..ad33974 100644
--- a/c++/contourgl/shaders.cpp
+++ b/c++/contourgl/shaders.cpp
@@ -25,18 +25,6 @@
using namespace std;
-Shaders* Shaders::instance = NULL;
-
-void Shaders::initialize() {
- assert(!instance);
- instance = new Shaders();
-}
-
-void Shaders::deinitialize() {
- assert(instance);
- delete instance;
-}
-
Shaders::Shaders():
simple_vertex_id(),
simpleProgramId(),
@@ -149,14 +137,12 @@ void Shaders::check_program(GLuint id, const char *name) {
}
void Shaders::simple() {
- assert(instance);
- glUseProgram(instance->simpleProgramId);
+ glUseProgram(simpleProgramId);
}
void Shaders::color(const Color &c) {
- assert(instance);
- glUseProgram(instance->colorProgramId);
- glUniform4fv(instance->colorUniform, 1, c.channels);
+ glUseProgram(colorProgramId);
+ glUniform4fv(colorUniform, 1, c.channels);
}
diff --git a/c++/contourgl/shaders.h b/c++/contourgl/shaders.h
index 33d9fa5..649ce12 100644
--- a/c++/contourgl/shaders.h
+++ b/c++/contourgl/shaders.h
@@ -15,6 +15,9 @@
along with this program. If not, see .
*/
+#ifndef _SHADERS_H_
+#define _SHADERS_H_
+
#include
#include
#include
@@ -22,7 +25,7 @@
#include "rendersw.h"
class Shaders {
-private:
+public:
GLuint simple_vertex_id;
GLuint simpleProgramId;
@@ -30,18 +33,14 @@ private:
GLuint colorProgramId;
GLint colorUniform;
- Shaders();
- ~Shaders();
-
- static Shaders *instance;
-
void check_shader(GLuint id, const char *src);
void check_program(GLuint id, const char *name);
-public:
- static void initialize();
- static void deinitialize();
+ Shaders();
+ ~Shaders();
- static void simple();
- static void color(const Color &c);
+ void simple();
+ void color(const Color &c);
};
+
+#endif
diff --git a/c++/contourgl/test.cpp b/c++/contourgl/test.cpp
index 3ac52f9..d973de4 100644
--- a/c++/contourgl/test.cpp
+++ b/c++/contourgl/test.cpp
@@ -15,267 +15,53 @@
along with this program. If not, see .
*/
-#include
-
#include
#include
-#include
-
-#include
-#include
-#include
#include "test.h"
-
-#include "contour.h"
-#include "rendersw.h"
#include "contourbuilder.h"
-#include "shaders.h"
#include "triangulator.h"
+#include "measure.h"
+#include "utils.h"
using namespace std;
-class Test::Helper {
-public:
- static void save_rgba(
- const void *buffer,
- int width,
- int height,
- bool flip,
- const string &filename )
- {
- // create file
- ofstream f(("results/" + filename).c_str(), ofstream::out | ofstream::trunc | ofstream::binary);
-
- // write header
- unsigned char targa_header[] = {
- 0, // Length of the image ID field (0 - no ID field)
- 0, // Whether a color map is included (0 - no colormap)
- 2, // Compression and color types (2 - uncompressed true-color image)
- 0, 0, 0, 0, 0, // Color map specification (not need for us)
- 0, 0, // X-origin
- 0, 0, // Y-origin
- (unsigned char)(width & 0xff), // Image width
- (unsigned char)(width >> 8),
- (unsigned char)(height & 0xff), // Image height
- (unsigned char)(height >> 8),
- 32, // Bits per pixel
- 0 // Image descriptor (keep zero for capability)
- };
- f.write((char*)targa_header, sizeof(targa_header));
-
- // write data
- if (flip) {
- int line_size = 4*width;
- const char *end = (char*)buffer;
- const char *current = end + height*line_size;
- while(current > end) {
- current -= line_size;
- f.write(current, line_size);
- }
- } else {
- f.write((const char*)buffer, 4*width*height);
- }
- }
-
- static void save_viewport(const string &filename) {
- glFinish();
-
- GLint vp[4] = {};
- glGetIntegerv(GL_VIEWPORT, vp);
-
- GLint draw_buffer = 0, read_buffer = 0;
- glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_buffer);
- glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_buffer);
- if (draw_buffer != read_buffer) {
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint)read_buffer);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, (GLuint)draw_buffer);
- glBlitFramebuffer(vp[0], vp[1], vp[2], vp[3], vp[0], vp[1], vp[2], vp[3], GL_COLOR_BUFFER_BIT, GL_NEAREST);
- glFinish();
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint)draw_buffer);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, (GLuint)read_buffer);
- }
-
- char *buffer = new char[vp[2]*vp[3]*4];
- glReadPixels(vp[0], vp[1], vp[2], vp[3], GL_BGRA, GL_UNSIGNED_BYTE, buffer);
-
-
- save_rgba(buffer, vp[2], vp[3], false, filename);
- delete buffer;
- }
+void Test::draw_contour(int start, int count, bool even_odd, bool invert, const Color &color) {
+ glEnable(GL_STENCIL_TEST);
- static void save_surface(const Surface &surface, const string &filename) {
- unsigned char *buffer = new unsigned char[4*surface.count()];
- unsigned char *j = buffer;
- for(Color *i = surface.data, *end = i + surface.count(); i != end; ++i, j += 4) {
- j[0] = (unsigned char)roundf(max(0.f, min(1.f, i->b))*255.f);
- j[1] = (unsigned char)roundf(max(0.f, min(1.f, i->g))*255.f);
- j[2] = (unsigned char)roundf(max(0.f, min(1.f, i->r))*255.f);
- j[3] = (unsigned char)roundf(max(0.f, min(1.f, i->a))*255.f);
- }
- save_rgba(buffer, surface.width, surface.height, false, filename);
- delete buffer;
- }
-
- static void draw_contour_strip(const vector &c) {
- glBegin(GL_TRIANGLE_STRIP);
- for(vector::const_iterator i = c.begin(); i != c.end(); ++i) {
- glVertex2d(i->x, i->y);
- glVertex2d(-1.0, i->y);
- }
- glEnd();
- }
-
- static void draw_contour_strip(const Contour &c) {
- glBegin(GL_TRIANGLE_STRIP);
- const Contour::ChunkList &chunks = c.get_chunks();
- Vector prev;
- for(Contour::ChunkList::const_iterator i = chunks.begin(); i != chunks.end(); ++i) {
- if ( i->type == Contour::LINE
- || i->type == Contour::CLOSE)
- {
- glVertex2d(i->p1.x, i->p1.y);
- glVertex2d(-1.0, i->p1.y);
- prev.x = -1.0;
- prev.y = i->p1.y;
- } else {
- glVertex2d(prev.x, prev.y);
- glVertex2d(prev.x, prev.y);
- glVertex2d(i->p1.x, i->p1.y);
- glVertex2d(i->p1.x, i->p1.y);
- prev = i->p1;
- }
- }
- glEnd();
- }
-
- static void draw_contour_strip(const int &count) {
- glDrawArrays(GL_TRIANGLE_STRIP, 4, count);
- }
-
- template
- static void draw_contour(const T &c, bool even_odd, bool invert) {
- glEnable(GL_STENCIL_TEST);
-
- // render mask
- GLint draw_buffer;
- glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
- glDrawBuffer(GL_NONE);
- glClear(GL_STENCIL_BUFFER_BIT);
- glStencilFunc(GL_ALWAYS, 0, 0);
- if (even_odd) {
- glStencilOp(GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);
- } else {
- glStencilOpSeparate(GL_FRONT, GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);
- glStencilOpSeparate(GL_BACK, GL_DECR_WRAP, GL_DECR_WRAP, GL_DECR_WRAP);
- }
- Shaders::simple();
- draw_contour_strip(c);
- glDrawBuffer((GLenum)draw_buffer);
-
- // fill mask
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- if (!even_odd && !invert)
- glStencilFunc(GL_NOTEQUAL, 0, -1);
- if (!even_odd && invert)
- glStencilFunc(GL_EQUAL, 0, -1);
- if ( even_odd && !invert)
- glStencilFunc(GL_EQUAL, 1, 1);
- if ( even_odd && invert)
- glStencilFunc(GL_EQUAL, 0, 1);
-
- Shaders::color(Color(0.f, 0.f, 1.f, 1.f));
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- glDisable(GL_STENCIL_TEST);
- }
-
- static void draw_contour(int start, int count, bool even_odd, bool invert, const Color &color) {
- glEnable(GL_STENCIL_TEST);
-
- // render mask
- GLint draw_buffer;
- glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
- glDrawBuffer(GL_NONE);
- glClear(GL_STENCIL_BUFFER_BIT);
- glStencilFunc(GL_ALWAYS, 0, 0);
- if (even_odd) {
- glStencilOp(GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);
- } else {
- glStencilOpSeparate(GL_FRONT, GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);
- glStencilOpSeparate(GL_BACK, GL_DECR_WRAP, GL_DECR_WRAP, GL_DECR_WRAP);
- }
- Shaders::simple();
- glDrawArrays(GL_TRIANGLE_STRIP, start, count);
- glDrawBuffer((GLenum)draw_buffer);
-
- // fill mask
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- if (!even_odd && !invert)
- glStencilFunc(GL_NOTEQUAL, 0, -1);
- if (!even_odd && invert)
- glStencilFunc(GL_EQUAL, 0, -1);
- if ( even_odd && !invert)
- glStencilFunc(GL_EQUAL, 1, 1);
- if ( even_odd && invert)
- glStencilFunc(GL_EQUAL, 0, 1);
-
- Shaders::color(color);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- glDisable(GL_STENCIL_TEST);
- }
-
- static Vector get_frame_size() {
- int vp[4] = {};
- glGetIntegerv(GL_VIEWPORT, vp);
- return Vector((Real)vp[2], (Real)vp[3]);
- }
-
-};
-
-Test::Wrapper::Wrapper(const std::string &filename):
- filename(filename),
- surface(),
- tga(filename.size() > 4 && filename.substr(filename.size()-4, 4) == ".tga"),
- t(get_clock())
-{ }
-
-Test::Wrapper::Wrapper(const std::string &filename, Surface &surface):
- filename(filename),
- surface(&surface),
- tga(filename.size() > 4 && filename.substr(filename.size()-4, 4) == ".tga"),
- t(get_clock())
-{ }
-
-Test::Wrapper::~Wrapper() {
- if (!surface && tga) glFinish();
- Real ms = 1000.0*(Real)(get_clock() - t)/(Real)(CLOCKS_PER_SEC);
- cout << setw(8) << fixed << setprecision(3)
- << ms << " ms - " << filename << flush << endl;
-
- if (tga) {
- if (surface)
- Helper::save_surface(*surface, filename);
- else
- Helper::save_viewport(filename);
- }
-
- if (surface) {
- surface->clear();
+ // render mask
+ GLint draw_buffer;
+ glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
+ glDrawBuffer(GL_NONE);
+ glClear(GL_STENCIL_BUFFER_BIT);
+ glStencilFunc(GL_ALWAYS, 0, 0);
+ if (even_odd) {
+ glStencilOp(GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);
} else {
- glClear(GL_COLOR_BUFFER_BIT);
- glFinish();
- }
-}
-
-void Test::check_gl(const std::string &s) {
- GLenum error = glGetError();
- if (error) {
- cout << s << " GL error: 0x" << setbase(16) << error << setbase(10) << endl;
- }
+ glStencilOpSeparate(GL_FRONT, GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);
+ glStencilOpSeparate(GL_BACK, GL_DECR_WRAP, GL_DECR_WRAP, GL_DECR_WRAP);
+ }
+ e.shaders.simple();
+ glDrawArrays(GL_TRIANGLE_STRIP, start, count);
+ glDrawBuffer((GLenum)draw_buffer);
+
+ // fill mask
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ if (!even_odd && !invert)
+ glStencilFunc(GL_NOTEQUAL, 0, -1);
+ if (!even_odd && invert)
+ glStencilFunc(GL_EQUAL, 0, -1);
+ if ( even_odd && !invert)
+ glStencilFunc(GL_EQUAL, 1, 1);
+ if ( even_odd && invert)
+ glStencilFunc(GL_EQUAL, 0, 1);
+
+ e.shaders.color(color);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glDisable(GL_STENCIL_TEST);
}
void Test::load(std::vector &contours, const std::string &filename) {
@@ -354,63 +140,12 @@ void Test::load(std::vector &contours, const std::string &filename)
}
-void Test::test1() {
- // OpenGl 2 code
-
- vector c;
- ContourBuilder::build_simple(c);
- cout << c.size() << " vertices" << endl;
-
- glPushAttrib(GL_ALL_ATTRIB_BITS);
-
- int random = (int)get_clock();
- {
- Wrapper t("test_1_control_timer_200000_simple_ops");
- int j = random;
- for(long long i = 0; i < 200000; ++i)
- if (j > i) ++j;
- glColor4f(j%2, j%2, j%2, j%2);
- }
-
- glColor4f(0.f, 0.f, 1.f, 1.f);
-
- {
- Wrapper t("test_1_contour.tga");
- glBegin(GL_LINE_STRIP);
- for(vector::const_iterator i = c.begin(); i != c.end(); ++i)
- glVertex2d(i->x, i->y);
- glEnd();
- }
-
- {
- Wrapper t("test_1_contour_fill.tga");
- Helper::draw_contour(c, false, false);
- }
-
- {
- Wrapper t("test_1_contour_fill_invert.tga");
- Helper::draw_contour(c, false, true);
- }
-
- {
- Wrapper t("test_1_contour_evenodd.tga");
- Helper::draw_contour(c, true, false);
- }
-
- {
- Wrapper t("test_1_contour_evenodd_invert.tga");
- Helper::draw_contour(c, true, true);
- }
-
- glPopAttrib();
-}
-
void Test::test2() {
Contour c, cc;
ContourBuilder::build(cc);
cout << cc.get_chunks().size() << " commands" << endl;
- Vector frame_size = Helper::get_frame_size();
+ Vector frame_size = Utils::get_frame_size();
Rect bounds;
bounds.p0 = Vector(-1.0, -1.0);
@@ -418,7 +153,7 @@ void Test::test2() {
Vector min_size(1.75/frame_size.x, 1.75/frame_size.y);
{
- Wrapper t("test_2_split");
+ Measure t("test_2_split");
cc.split(c, bounds, min_size);
}
@@ -431,7 +166,7 @@ void Test::test2() {
vector< vec2 > vertices;
{
- Wrapper t("test_2_init_buffer");
+ Measure t("test_2_init_buffer");
vertices.resize(4+4*chunks.size());
glGenBuffers(1, &buffer_id);
glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
@@ -448,7 +183,7 @@ void Test::test2() {
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_TRUE, 0, NULL);
- Shaders::color(Color(0.f, 0.f, 1.f, 1.f));
+ e.shaders.color(Color(0.f, 0.f, 1.f, 1.f));
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
glFinish();
glClear(GL_COLOR_BUFFER_BIT);
@@ -456,7 +191,7 @@ void Test::test2() {
}
{
- Wrapper t("test_2_prepare_data");
+ Measure t("test_2_prepare_data");
vertices.push_back(vec2(bounds.p0.x, bounds.p0.y));
vertices.push_back(vec2(bounds.p0.x, bounds.p1.y));
vertices.push_back(vec2(bounds.p1.x, bounds.p0.y));
@@ -480,7 +215,7 @@ void Test::test2() {
}
{
- Wrapper t("test_2_send_data");
+ Measure t("test_2_send_data");
glBufferSubData( GL_ARRAY_BUFFER,
0,
vertices.size()*sizeof(vertices.front()),
@@ -488,35 +223,35 @@ void Test::test2() {
}
{
- Wrapper t("test_2_simple_fill.tga");
+ Measure t("test_2_simple_fill.tga");
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
{
- Wrapper t("test_2_array.tga");
+ Measure t("test_2_array.tga");
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDrawArrays(GL_TRIANGLE_STRIP, 4, count);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
{
- Wrapper t("test_2_contour_fill.tga");
- Helper::draw_contour(count, false, false);
+ Measure t("test_2_contour_fill.tga");
+ draw_contour(4, count, false, false, Color(0.f, 0.f, 1.f, 1.f));
}
{
- Wrapper t("test_2_contour_fill_invert.tga");
- Helper::draw_contour(count, false, true);
+ Measure t("test_2_contour_fill_invert.tga");
+ draw_contour(4, count, false, true, Color(0.f, 0.f, 1.f, 1.f));
}
{
- Wrapper t("test_2_contour_evenodd.tga");
- Helper::draw_contour(count, true, false);
+ Measure t("test_2_contour_evenodd.tga");
+ draw_contour(4, count, true, false, Color(0.f, 0.f, 1.f, 1.f));
}
{
- Wrapper t("test_2_contour_evenodd_invert.tga");
- Helper::draw_contour(count, true, true);
+ Measure t("test_2_contour_evenodd_invert.tga");
+ draw_contour(4, count, true, true, Color(0.f, 0.f, 1.f, 1.f));
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -528,7 +263,7 @@ void Test::test3() {
ContourBuilder::build(c);
cout << c.get_chunks().size() << " commands" << endl;
- Vector frame_size = Helper::get_frame_size();
+ Vector frame_size = Utils::get_frame_size();
int width = (int)frame_size.x;
int height = (int)frame_size.y;
@@ -548,7 +283,7 @@ void Test::test3() {
Color color(0.f, 0.f, 1.f, 1.f);
{
- Wrapper t("test_3_build_polyspan");
+ Measure t("test_3_build_polyspan");
c.to_polyspan(polyspan);
}
@@ -557,7 +292,7 @@ void Test::test3() {
glPushAttrib(GL_ALL_ATTRIB_BITS);
glColor4d(0.0, 0.0, 1.0, 1.0);
{
- Wrapper t("test_3_polyspan_gl_lines.tga");
+ Measure t("test_3_polyspan_gl_lines.tga");
glBegin(GL_LINE_STRIP);
for(Polyspan::cover_array::const_iterator i = polyspan.get_covers().begin(); i != polyspan.get_covers().end(); ++i)
glVertex2d((double)i->x/1024.0*2.0 - 1.0, (double)i->y/1024.0*2.0 - 1.0);
@@ -567,33 +302,33 @@ void Test::test3() {
{
- Wrapper t("test_3_polyspan_sort");
+ Measure t("test_3_polyspan_sort");
polyspan.sort_marks();
}
{
- Wrapper t("test_3_polyspan_fill.tga", surface);
+ Measure t("test_3_polyspan_fill.tga", surface);
RenderSW::polyspan(surface, polyspan, color, false, false);
}
{
- Wrapper t("test_3_polyspan_fill_invert.tga", surface);
+ Measure t("test_3_polyspan_fill_invert.tga", surface);
RenderSW::polyspan(surface, polyspan, color, false, true);
}
{
- Wrapper t("test_3_polyspan_evenodd.tga", surface);
+ Measure t("test_3_polyspan_evenodd.tga", surface);
RenderSW::polyspan(surface, polyspan, color, true, false);
}
{
- Wrapper t("test_3_polyspan_evenodd_invert.tga", surface);
+ Measure t("test_3_polyspan_evenodd_invert.tga", surface);
RenderSW::polyspan(surface, polyspan, color, true, true);
}
}
void Test::test4() {
- Vector frame_size = Helper::get_frame_size();
+ Vector frame_size = Utils::get_frame_size();
int width = (int)frame_size.x;
int height = (int)frame_size.y;
@@ -631,7 +366,7 @@ void Test::test4() {
vector counts(contours_gl.size());
{
- Wrapper t("test_4_gl_init_buffer");
+ Measure t("test_4_gl_init_buffer");
vertices.resize(4 + 4*commands_count + 2*contours_gl.size());
glGenBuffers(1, &buffer_id);
glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
@@ -648,7 +383,7 @@ void Test::test4() {
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_TRUE, 0, NULL);
- Shaders::color(Color(0.f, 0.f, 1.f, 1.f));
+ e.shaders.color(Color(0.f, 0.f, 1.f, 1.f));
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
glFinish();
glClear(GL_COLOR_BUFFER_BIT);
@@ -656,7 +391,7 @@ void Test::test4() {
}
{
- Wrapper t("test_4_gl_stencil_prepare_data");
+ Measure t("test_4_gl_stencil_prepare_data");
vertices.push_back(vec2(bounds_gl.p0.x, bounds_gl.p0.y));
vertices.push_back(vec2(bounds_gl.p0.x, bounds_gl.p1.y));
vertices.push_back(vec2(bounds_gl.p1.x, bounds_gl.p0.y));
@@ -684,7 +419,7 @@ void Test::test4() {
}
{
- Wrapper t("test_4_gl_stencil_send_data");
+ Measure t("test_4_gl_stencil_send_data");
glBufferSubData( GL_ARRAY_BUFFER,
0,
vertices.size()*sizeof(vertices.front()),
@@ -692,14 +427,14 @@ void Test::test4() {
}
{
- Wrapper t("test_4_gl_stencil_points.tga");
+ Measure t("test_4_gl_stencil_points.tga");
glDrawArrays(GL_POINTS, 0, vertices.size());
}
{
- Wrapper t("test_4_gl_stencil_render.tga");
+ Measure t("test_4_gl_stencil_render.tga");
for(int i = 0; i < (int)contours_gl.size(); ++i) {
- Helper::draw_contour(
+ draw_contour(
starts[i],
counts[i],
contours_gl[i].invert,
@@ -719,7 +454,7 @@ void Test::test4() {
vertices.reserve(commands_count);
{
- Wrapper t("test_4_gl_init_index_buffer");
+ Measure t("test_4_gl_init_index_buffer");
triangles.resize(3*commands_count);
glGenBuffers(1, &index_buffer_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id);
@@ -732,7 +467,7 @@ void Test::test4() {
}
{
- Wrapper t("test_4_gl_triangulate");
+ Measure t("test_4_gl_triangulate");
int index_offset = 4;
for(int i = 0; i < (int)contours_gl.size(); ++i) {
triangle_starts[i] = (int)triangles.size();
@@ -745,7 +480,7 @@ void Test::test4() {
cout << triangles.size() << " triangles" << endl;
{
- Wrapper t("test_4_gl_triangles_prepare_vertices");
+ Measure t("test_4_gl_triangles_prepare_vertices");
for(int i = 0; i < (int)contours_gl.size(); ++i) {
const Contour::ChunkList &chunks = contours_gl[i].contour.get_chunks();
for(Contour::ChunkList::const_iterator j = chunks.begin(); j != chunks.end(); ++j)
@@ -754,7 +489,7 @@ void Test::test4() {
}
{
- Wrapper t("test_4_gl_triangles_send_data");
+ Measure t("test_4_gl_triangles_send_data");
glBufferSubData( GL_ARRAY_BUFFER,
4*sizeof(vertices.front()),
vertices.size()*sizeof(vertices.front()),
@@ -766,9 +501,9 @@ void Test::test4() {
}
{
- Wrapper t("test_4_gl_triangles_render.tga");
+ Measure t("test_4_gl_triangles_render.tga");
for(int i = 0; i < (int)contours_gl.size(); ++i) {
- Shaders::color(contours_gl[i].color);
+ e.shaders.color(contours_gl[i].color);
glDrawElements(GL_TRIANGLES, triangle_counts[i], GL_UNSIGNED_INT, (char*)NULL + triangle_starts[i]*sizeof(int));
}
}
@@ -783,7 +518,7 @@ void Test::test4() {
vector polyspans(contours_sw.size());
{
- Wrapper t("test_4_sw_build_polyspans");
+ Measure t("test_4_sw_build_polyspans");
for(int i = 0; i < (int)contours_sw.size(); ++i) {
polyspans[i].init(0, 0, width, height);
contours_sw[i].contour.to_polyspan(polyspans[i]);
@@ -794,7 +529,7 @@ void Test::test4() {
Surface surface(width, height);
{
- Wrapper t("test_4_sw_render_polyspans.tga", surface);
+ Measure t("test_4_sw_render_polyspans.tga", surface);
for(int i = 0; i < (int)contours_sw.size(); ++i)
RenderSW::polyspan(surface, polyspans[i], contours_sw[i].color, contours_sw[i].evenodd, contours_sw[i].invert);
}
diff --git a/c++/contourgl/test.h b/c++/contourgl/test.h
index 0431fb8..68fac43 100644
--- a/c++/contourgl/test.h
+++ b/c++/contourgl/test.h
@@ -22,29 +22,10 @@
#include
#include "contour.h"
-#include "rendersw.h"
-
-class Surface;
-
-clock_t get_clock();
+#include "environment.h"
class Test {
public:
- class Wrapper {
- private:
- std::string filename;
- Surface *surface;
- bool tga;
- clock_t t;
-
- Wrapper(const Wrapper&): surface(), tga(), t() { }
- Wrapper& operator= (const Wrapper&) { return *this; }
- public:
- Wrapper(const std::string &filename);
- Wrapper(const std::string &filename, Surface &surface);
- ~Wrapper();
- };
-
struct ContourInfo {
bool invert;
bool antialias;
@@ -54,19 +35,18 @@ public:
ContourInfo(): invert(), antialias(), evenodd() { }
};
-private:
- class Helper;
-
-public:
- static void check_gl(const std::string &s = std::string());
+ Environment &e;
- static void load(std::vector &contours, const std::string &filename);
+ Test(Environment &e): e(e) { }
+ ~Test() { }
- static void test1();
- static void test2();
- static void test3();
+ void draw_contour(int start, int count, bool even_odd, bool invert, const Color &color);
+ void load(std::vector &contours, const std::string &filename);
- static void test4();
+ void test1();
+ void test2();
+ void test3();
+ void test4();
};
#endif
diff --git a/c++/contourgl/utils.cpp b/c++/contourgl/utils.cpp
new file mode 100644
index 0000000..f93fd3e
--- /dev/null
+++ b/c++/contourgl/utils.cpp
@@ -0,0 +1,111 @@
+/*
+ ......... 2015 Ivan Mahonin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+
+#include "utils.h"
+#include "glcontext.h"
+
+
+using namespace std;
+
+
+Vector Utils::get_frame_size() {
+ int vp[4] = {};
+ glGetIntegerv(GL_VIEWPORT, vp);
+ return Vector((Real)vp[2], (Real)vp[3]);
+}
+
+void Utils::save_rgba(
+ const void *buffer,
+ int width,
+ int height,
+ bool flip,
+ const string &filename )
+{
+ // create file
+ ofstream f(("results/" + filename).c_str(), ofstream::out | ofstream::trunc | ofstream::binary);
+
+ // write header
+ unsigned char targa_header[] = {
+ 0, // Length of the image ID field (0 - no ID field)
+ 0, // Whether a color map is included (0 - no colormap)
+ 2, // Compression and color types (2 - uncompressed true-color image)
+ 0, 0, 0, 0, 0, // Color map specification (not need for us)
+ 0, 0, // X-origin
+ 0, 0, // Y-origin
+ (unsigned char)(width & 0xff), // Image width
+ (unsigned char)(width >> 8),
+ (unsigned char)(height & 0xff), // Image height
+ (unsigned char)(height >> 8),
+ 32, // Bits per pixel
+ 0 // Image descriptor (keep zero for capability)
+ };
+ f.write((char*)targa_header, sizeof(targa_header));
+
+ // write data
+ if (flip) {
+ int line_size = 4*width;
+ const char *end = (char*)buffer;
+ const char *current = end + height*line_size;
+ while(current > end) {
+ current -= line_size;
+ f.write(current, line_size);
+ }
+ } else {
+ f.write((const char*)buffer, 4*width*height);
+ }
+}
+
+void Utils::save_viewport(const string &filename) {
+ glFinish();
+
+ GLint vp[4] = {};
+ glGetIntegerv(GL_VIEWPORT, vp);
+
+ GLint draw_buffer = 0, read_buffer = 0;
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_buffer);
+ glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_buffer);
+ if (draw_buffer != read_buffer) {
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint)read_buffer);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, (GLuint)draw_buffer);
+ glBlitFramebuffer(vp[0], vp[1], vp[2], vp[3], vp[0], vp[1], vp[2], vp[3], GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glFinish();
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint)draw_buffer);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, (GLuint)read_buffer);
+ }
+
+ char *buffer = new char[vp[2]*vp[3]*4];
+ glReadPixels(vp[0], vp[1], vp[2], vp[3], GL_BGRA, GL_UNSIGNED_BYTE, buffer);
+
+
+ save_rgba(buffer, vp[2], vp[3], false, filename);
+ delete buffer;
+}
+
+void Utils::save_surface(const Surface &surface, const string &filename) {
+ unsigned char *buffer = new unsigned char[4*surface.count()];
+ unsigned char *j = buffer;
+ for(Color *i = surface.data, *end = i + surface.count(); i != end; ++i, j += 4) {
+ j[0] = (unsigned char)roundf(max(0.f, min(1.f, i->b))*255.f);
+ j[1] = (unsigned char)roundf(max(0.f, min(1.f, i->g))*255.f);
+ j[2] = (unsigned char)roundf(max(0.f, min(1.f, i->r))*255.f);
+ j[3] = (unsigned char)roundf(max(0.f, min(1.f, i->a))*255.f);
+ }
+ save_rgba(buffer, surface.width, surface.height, false, filename);
+ delete buffer;
+}
diff --git a/c++/contourgl/utils.h b/c++/contourgl/utils.h
new file mode 100644
index 0000000..9639734
--- /dev/null
+++ b/c++/contourgl/utils.h
@@ -0,0 +1,42 @@
+/*
+ ......... 2015 Ivan Mahonin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef _UTILS_H_
+#define _UTILS_H_
+
+#include
+
+#include "geometry.h"
+#include "rendersw.h"
+
+class Utils {
+public:
+ static Vector get_frame_size();
+
+ static void save_rgba(
+ const void *buffer,
+ int width,
+ int height,
+ bool flip,
+ const std::string &filename );
+
+ static void save_viewport(const std::string &filename);
+
+ static void save_surface(const Surface &surface, const std::string &filename);
+};
+
+#endif