From 28e5289acd9276bbf281edb9d21a5662ea0e1956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Rom=C3=A9o?= Date: Fri, 19 Jun 2020 16:47:24 +0200 Subject: [PATCH] #299: Use OpenGL in rendering tests --- unittest/CMakeLists.txt | 31 +------ unittest/rendering/renderingtest.cpp | 127 ++++++++++++++++++--------- unittest/rendering/res/1.png | Bin 304 -> 0 bytes unittest/rendering/res/1.tga | Bin 0 -> 30018 bytes unittest/rendering/res/2.png | Bin 4602 -> 0 bytes unittest/rendering/res/2.tga | Bin 0 -> 30018 bytes 6 files changed, 90 insertions(+), 68 deletions(-) delete mode 100644 unittest/rendering/res/1.png create mode 100644 unittest/rendering/res/1.tga delete mode 100644 unittest/rendering/res/2.png create mode 100644 unittest/rendering/res/2.tga diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 88c640abf..4019e2fc3 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -118,42 +118,17 @@ endif(WITH_QT_UI) if(WITH_RENDERING_UNITTESTS) add_compile_definitions(SOURCE_DIR=\"${CMAKE_CURRENT_LIST_DIR}\") - # GDK-Pixbuf - find_package(GDK-Pixbuf 2.30 REQUIRED) - include_directories(${GDK-PIXBUF_INCLUDE_DIRS}) - - #GDK - find_package(GDK REQUIRED) - include_directories(${GDK_INCLUDE_DIRS}) - - #GLib - set(GLIB_FIND_COMPONENTS gobject) - find_package(GLib REQUIRED) - include_directories(${GLIB_INCLUDE_DIRS}) - - # Cairo - find_package(Cairo 1.13 REQUIRED) - include_directories(${CAIRO_INCLUDE_DIRS}) - - # Pango - find_package(Pango 1.36 REQUIRED) - include_directories(${PANGO_INCLUDE_DIRS}) - link_directories(${PANGO_LIBRARIES}) - # Boost set(Boost_USE_MULTITHREADED ON) find_package(Boost COMPONENTS program_options filesystem system log REQUIRED) include_directories(${Boost_INCLUDE_DIRS}) + find_package(glfw3 3.3 REQUIRED) + set(EXTRA_LIBS ${EXTRA_LIBS} - ${CAIRO_LIBRARIES} - ${PANGO_LIBRARIES} - ${GDK-PIXBUF_LIBRARIES} - ${GDK_LIBRARIES} - ${GLIB_GOBJECT_LIBRARIES} - ${GLIB_LIBRARIES} ${Boost_LIBRARIES} + glfw ) set(src diff --git a/unittest/rendering/renderingtest.cpp b/unittest/rendering/renderingtest.cpp index 981eca41b..a4245da1e 100644 --- a/unittest/rendering/renderingtest.cpp +++ b/unittest/rendering/renderingtest.cpp @@ -1,21 +1,23 @@ -#include +#include +#include #include + #ifndef WIN32 #include #endif -#include #include #include #include -#include #include #include #include #include #include #include +#include +#include #define DEFAULT_IMAGE_WIDTH 100 #define DEFAULT_IMAGE_HEIGHT 100 @@ -50,60 +52,105 @@ void render(const std::string& dxf, const std::string& output, unsigned int imag ); _canvas->background().connect(_gradientBackground.get()); - LcPainter* lcPainter = new LcCairoPainter(imageWidth, imageHeight, nullptr);; + lc::viewer::LcPainter* lcPainter; + if(!glfwInit()) { + LOG_ERROR << "Failed to initialize GLFW"; + return; + } + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + + GLFWwindow* window; + window = glfwCreateWindow(imageWidth, imageHeight, "LibreCAD", nullptr, nullptr); + if(window == nullptr) { + const char* description; + glfwGetError(&description); + glfwTerminate(); + FAIL() << "Failed opening GLFW: " << description << std::endl; + } + + glfwMakeContextCurrent(window); + + glewExperimental = GL_TRUE; + GLenum err = glewInit(); + + if (err != GLEW_OK) { + FAIL() << "GLEW Error: " << glewGetErrorString(err) << std::endl; + } + + LOG_INFO << (char*) glGetString(GL_VERSION) << std::endl; + + lcPainter = lc::viewer::createOpenGLPainter(nullptr, imageWidth, imageHeight); + lcPainter->create_resources(); + _canvas->setPainter(lcPainter); + + // Set device width/height _canvas->newDeviceSize(imageWidth, imageHeight); + lcPainter->new_device_size(imageWidth, imageHeight); + lc::persistence::File::open(_document, dxf, lc::persistence::File::LIBDXFRW); _canvas->setDisplayArea(*lcPainter, lc::geo::Area(lc::geo::Coordinate(x, y), w, h)); - _canvas->render(*lcPainter, VIEWER_BACKGROUND); - _canvas->render(*lcPainter, VIEWER_DOCUMENT); - _canvas->render(*lcPainter, VIEWER_FOREGROUND); + _canvas->render(*lcPainter, lc::viewer::VIEWER_BACKGROUND); + _canvas->render(*lcPainter, lc::viewer::VIEWER_DOCUMENT); + _canvas->render(*lcPainter, lc::viewer::VIEWER_FOREGROUND); + + glfwSwapBuffers(window); + + FILE* out = fopen(output.c_str(), "wb"); + char* pixel_data = new char[3*imageWidth*imageHeight]; + short TGAhead[] = { 0, 2, 0, 0, 0, 0, static_cast(imageWidth), static_cast(imageHeight), 24 }; + + glReadBuffer(GL_FRONT); + glReadPixels(0, 0, imageWidth, imageHeight, GL_BGR, GL_UNSIGNED_BYTE, pixel_data); + + fwrite(&TGAhead,sizeof(TGAhead),1,out); + fwrite(pixel_data, 3*imageWidth*imageHeight, 1, out); + fclose(out); - static_cast*>(lcPainter)->writePNG(output); + delete[] pixel_data; + glfwDestroyWindow(window); delete lcPainter; } bool checkRender(const std::string& image1, const std::string& image2, float tolerance) { - GError* error1 = NULL; - GError* error2 = NULL; - - auto pixbuf1 = gdk_pixbuf_new_from_file(image1.c_str(), &error1); - auto pixbuf2 = gdk_pixbuf_new_from_file(image2.c_str(), &error2); - - if(error1) { - std::cerr << error1->message << std::endl; - g_error_free(error1); - return false; - } - if(error2) { - std::cerr << error2->message << std::endl; - g_error_free(error2); + std::fstream f1; + f1.open(image1, std::ios::in); + if(f1.fail()) { + std::cerr << "File " << image1 << " can't be opened" << std::endl; return false; } - if(gdk_pixbuf_get_width(pixbuf1) != gdk_pixbuf_get_width(pixbuf2) || - gdk_pixbuf_get_height(pixbuf1) != gdk_pixbuf_get_height(pixbuf2) || - gdk_pixbuf_get_n_channels(pixbuf1) != gdk_pixbuf_get_n_channels(pixbuf2)) { + std::fstream f2; + f2.open(image2, std::ios::in); + if(f2.fail()) { + std::cerr << "File " << image2 << " can't be opened" << std::endl; return false; } auto channelTolerance = 256.0 * (tolerance / 100.0); - auto nbPixels = gdk_pixbuf_get_height(pixbuf1) * gdk_pixbuf_get_rowstride(pixbuf1); + char c1 = '0'; + char c2 = '0'; + while((c1 != EOF) && (c2 != EOF)){ + c1 = f1.get(); + c2 = f2.get(); - auto pixels1 = gdk_pixbuf_get_pixels(pixbuf1); - auto pixels2 = gdk_pixbuf_get_pixels(pixbuf2); + if(c1 < c2 - channelTolerance || c1 > c2 + channelTolerance){ + return false; + } - for(auto i = 0; i < nbPixels; i++) { - auto pixel1 = pixels1[i]; - auto pixel2 = pixels2[i]; - if(pixel1 < pixel2 - channelTolerance || pixel1 > pixel2 + channelTolerance) { - std::cerr << "Pixel " << i << " failed: " << (int) pixel1 << " - " << (int) pixel2 << " with tolerance " << channelTolerance << std::endl; + if((c1 == EOF) ^ (c2 == EOF)) { return false; } } + f1.close(); + f2.close(); return true; } @@ -142,7 +189,7 @@ TEST(RenderingTest, Test) { unsigned int testNumber = 0; bool dxfFound = false; - bool pngFound = false; + bool tgaFound = false; bool configFound = false; for(auto i = 0; i < nbFiles; i++) { @@ -156,23 +203,23 @@ TEST(RenderingTest, Test) { if(newNumber != testNumber) { testNumber = newNumber; dxfFound = false; - pngFound = false; + tgaFound = false; configFound = false; } if(strcmp(extension, "dxf") == 0) { dxfFound = true; } - else if(strcmp(extension, "png") == 0) { - pngFound = true; + else if(strcmp(extension, "tga") == 0) { + tgaFound = true; } else if(strcmp(extension, "cfg") == 0) { configFound = true; } - if(dxfFound && pngFound && configFound) { + if(dxfFound && tgaFound && configFound) { auto base = std::string(resDir) + std::to_string(newNumber); - auto expectedFile = base + ".png"; + auto expectedFile = base + ".tga"; auto dxfFile = base + ".dxf"; auto resultFile = base + ".out"; auto configFile = base + ".cfg"; @@ -193,7 +240,7 @@ TEST(RenderingTest, Test) { ASSERT_TRUE(checkRender(expectedFile, resultFile, tolerance)) << "Failed with " << expectedFile; dxfFound = false; //Prevent running the test more than once - pngFound = false; + tgaFound = false; configFound = false; } } diff --git a/unittest/rendering/res/1.png b/unittest/rendering/res/1.png deleted file mode 100644 index f2bcf851fa126fad215c8291cd0540efb4f49da8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^DImh3!j%M4Y+bmLK#HvkR}x6Eb>T_^DYh%x@;Qfytgl0b^B3s(|Iv321}0x7mGTuC6s)`cqx zq}aM}C4m%M7p^3bV(Y?{1X65WxROAMtqWHYNU?R{N&+diE?h|<#ny!@38dJ%a3z5h zTNkb*kYek?l>}03UAU4!imeM*5=gOi;YtE2wk}*rAjQ^&D+#37x^N|d6k8XrB#>h3 m!j%M4Y+bmLK#HvkR}x6Eb>T_^VgdvR5FkK+009C&5O@HY1lN-Q literal 0 HcmV?d00001 diff --git a/unittest/rendering/res/2.png b/unittest/rendering/res/2.png deleted file mode 100644 index 2fc83fabb1d9f86c8df805739e12df5f3e0010f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4602 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 diff --git a/unittest/rendering/res/2.tga b/unittest/rendering/res/2.tga new file mode 100644 index 0000000000000000000000000000000000000000..374ed8e8ade2d27e91af1440df0ad0021c8b3953 GIT binary patch literal 30018 zcmeI1OLCkc41}kAiX6~a_bp}-RZ&(^0z~TpKa(&EM?mXStL-?8yk1|g-_Q5!`}ODd zaR0ms+yrg{H-VeLP2lqr_?dk^f5n6iN=Q=>D4TLVS3n7v%v<#)_{n15;=Zn@av-;k zk8t~bzr_uHr0KZ$5hds2n_joamyHvYE!e8HpdWzpu{MtML@Q53+>x zB#Wa2qCBNcU(HW3Swj@V%2Q47)l1<%OGwwq_UImA>Y8=nzD$USu^NTr*3ybe*N}tORgQ`Z^5c0ylHMGJUB6 zOvj#(45uMvZf1;I9k0O`+G0ASIMD;v^QX4)5fU)9ORItjP61lKOS99yA&vE z8-q9Txg)~pUNH=|fHGx}`zbg&*v__19Fv$w#EaluyBEw0%b3Si7f8W1SjI{q!i-z#^hhnOua%3qClB|^U>N)dj2rP zT@cFM%Z)e$S2DaVg6%cRQOBp72qtm6PO!ZNT5on52+j(&Ta#(^I}HS91>4)*9XAdS zjutZJ>*9@q?aT=lCL1PkZOq+RAl7!$>z~@&ikhaov5{UHinQ0^OnuhkQcqi0pqsJM z7|VsuXW6Jw+KV?uFk*^(<{+pd?h?eMi?1dK;^;`g+Oj9Hl)VH*9IcDH^{W$0*-Jpg(Y?E` zaozMRa?Po0-@d`F6$TQS0ws>Y-5u@e1`>e+C610|<1M)!PNv1PB0|=JSsY%f1-3UV z-cw{5$l}ynw@kWeFYA`2b;{@zNW10;JGyTPxi=|uQy|^FMr67lJ#{%Lm+^^lg0hGX zr`PgP2w6`wD2_^jC^iuO>cmp`$RbJ($P+%IY=rBP>7>a5W^r`e)+wZ~KRSH$%7l@? zbWb#sJ|d3H;;l_Z#I5L!m=`GUxPKyOOqV@n`>DBl8p`W~h94ZQ1fo2BoMB~`fBuQS zS%-hWPIGu{TxS|P(A9yK`1j0F-i|WE5!D4beB9&-9_mc=`YE?h&DGODUUxd*ISbj{ zr&+zlYQAslNLSg2zD6K*Z#uAsA5sT*47MK