diff options
-rw-r--r-- | src/export.cc | 15 | ||||
-rw-r--r-- | src/openscad.cc | 11 | ||||
-rw-r--r-- | src/polyset.cc | 280 | ||||
-rw-r--r-- | src/transform.cc | 62 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 39 | ||||
-rw-r--r-- | tests/FindGLEW.cmake | 15 | ||||
-rw-r--r-- | tests/OffscreenContext.cc | 139 | ||||
-rw-r--r-- | tests/OffscreenContext.h | 6 | ||||
-rw-r--r-- | tests/OffscreenView.cc | 5 | ||||
-rw-r--r-- | tests/csgtermtest.cc | 8 | ||||
-rw-r--r-- | tests/opencsgtest.cc | 4 |
11 files changed, 579 insertions, 5 deletions
diff --git a/src/export.cc b/src/export.cc index 6c427dd..9c23600 100644 --- a/src/export.cc +++ b/src/export.cc @@ -53,6 +53,17 @@ void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDial setlocale(LC_NUMERIC, "C"); // Ensure radix is . (not ,) in output +<<<<<<< HEAD + std::ofstream output(filename.toUtf8()); + if (!output.is_open()) { + PRINTA("Can't open STL file \"%1\" for STL export: %2", + filename, QString(strerror(errno))); + set_output_handler(NULL, NULL); + return; + } + +======= +>>>>>>> upstream/visitor output << "solid OpenSCAD_Model\n"; int facet_count = 0; @@ -111,6 +122,10 @@ void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDial } output << "endsolid OpenSCAD_Model\n"; +<<<<<<< HEAD + output.close(); +======= +>>>>>>> upstream/visitor setlocale(LC_NUMERIC, ""); // Set default locale } diff --git a/src/openscad.cc b/src/openscad.cc index fd74de4..203706d 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -317,6 +317,15 @@ int main(int argc, char **argv) } } +<<<<<<< HEAD + if (root_N.dim == 3 && !root_N.p3.is_simple()) { + fprintf(stderr, "Object isn't a valid 2-manifold! Modify your design.\n"); + exit(1); + } + + if (stl_output_file) + export_stl(&root_N, stl_output_file, NULL); +======= if (stl_output_file) { if (root_N.dim != 3) { fprintf(stderr, "Current top level object is not a 3D object.\n"); @@ -335,6 +344,7 @@ int main(int argc, char **argv) fstream.close(); } } +>>>>>>> upstream/visitor if (off_output_file) { if (root_N.dim != 3) { @@ -415,4 +425,3 @@ int main(int argc, char **argv) return rc; } - diff --git a/src/polyset.cc b/src/polyset.cc index 23b9876..7f3818f 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -314,5 +314,285 @@ BoundingBox PolySet::getBoundingBox() const bbox.extend(p); } } +<<<<<<< HEAD +}; + +CGAL_Nef_polyhedron PolySet::render_cgal_nef_polyhedron() const +{ + if (this->is2d) + { +#if 0 + // This version of the code causes problems in some cases. + // Example testcase: import_dxf("testdata/polygon8.dxf"); + // + typedef std::list<CGAL_Nef_polyhedron2::Point> point_list_t; + typedef point_list_t::iterator point_list_it; + std::list< point_list_t > pdata_point_lists; + std::list < std::pair < point_list_it, point_list_it > > pdata; + Grid2d<CGAL_Nef_polyhedron2::Point> grid(GRID_COARSE); + + for (int i = 0; i < this->polygons.size(); i++) { + pdata_point_lists.push_back(point_list_t()); + for (int j = 0; j < this->polygons[i].size(); j++) { + double x = this->polygons[i][j].x; + double y = this->polygons[i][j].y; + CGAL_Nef_polyhedron2::Point p; + if (grid.has(x, y)) { + p = grid.data(x, y); + } else { + p = CGAL_Nef_polyhedron2::Point(x, y); + grid.data(x, y) = p; + } + pdata_point_lists.back().push_back(p); + } + pdata.push_back(std::make_pair(pdata_point_lists.back().begin(), + pdata_point_lists.back().end())); + } + + CGAL_Nef_polyhedron2 N(pdata.begin(), pdata.end(), CGAL_Nef_polyhedron2::POLYGONS); + return CGAL_Nef_polyhedron(N); +#endif +#if 0 + // This version of the code works fine but is pretty slow. + // + CGAL_Nef_polyhedron2 N; + Grid2d<CGAL_Nef_polyhedron2::Point> grid(GRID_COARSE); + + for (int i = 0; i < this->polygons.size(); i++) { + std::list<CGAL_Nef_polyhedron2::Point> plist; + for (int j = 0; j < this->polygons[i].size(); j++) { + double x = this->polygons[i][j].x; + double y = this->polygons[i][j].y; + CGAL_Nef_polyhedron2::Point p; + if (grid.has(x, y)) { + p = grid.data(x, y); + } else { + p = CGAL_Nef_polyhedron2::Point(x, y); + grid.data(x, y) = p; + } + plist.push_back(p); + } + N += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); + } + + return CGAL_Nef_polyhedron(N); +#endif +#if 1 + // This version of the code does essentially the same thing as the 2nd + // version but merges some triangles before sending them to CGAL. This adds + // complexity but speeds up things.. + // + struct PolyReducer + { + Grid2d<int> grid; + QHash< QPair<int,int>, QPair<int,int> > egde_to_poly; + QHash< int, CGAL_Nef_polyhedron2::Point > points; + QHash< int, QList<int> > polygons; + int poly_n; + + void add_edges(int pn) + { + for (int j = 1; j <= this->polygons[pn].size(); j++) { + int a = this->polygons[pn][j-1]; + int b = this->polygons[pn][j % this->polygons[pn].size()]; + if (a > b) { a = a^b; b = a^b; a = a^b; } + if (this->egde_to_poly[QPair<int,int>(a, b)].first == 0) + this->egde_to_poly[QPair<int,int>(a, b)].first = pn; + else if (this->egde_to_poly[QPair<int,int>(a, b)].second == 0) + this->egde_to_poly[QPair<int,int>(a, b)].second = pn; + else + abort(); + } + } + + void del_poly(int pn) + { + for (int j = 1; j <= this->polygons[pn].size(); j++) { + int a = this->polygons[pn][j-1]; + int b = this->polygons[pn][j % this->polygons[pn].size()]; + if (a > b) { a = a^b; b = a^b; a = a^b; } + if (this->egde_to_poly[QPair<int,int>(a, b)].first == pn) + this->egde_to_poly[QPair<int,int>(a, b)].first = 0; + if (this->egde_to_poly[QPair<int,int>(a, b)].second == pn) + this->egde_to_poly[QPair<int,int>(a, b)].second = 0; + } + this->polygons.remove(pn); + } + + PolyReducer(const PolySet *ps) : grid(GRID_COARSE), poly_n(1) + { + int point_n = 1; + for (int i = 0; i < ps->polygons.size(); i++) { + for (int j = 0; j < ps->polygons[i].size(); j++) { + double x = ps->polygons[i][j].x; + double y = ps->polygons[i][j].y; + if (this->grid.has(x, y)) { + int idx = this->grid.data(x, y); + // Filter away two vertices with the same index (due to grid) + // This could be done in a more general way, but we'd rather redo the entire + // grid concept instead. + if (this->polygons[this->poly_n].indexOf(idx) == -1) { + this->polygons[this->poly_n].append(this->grid.data(x, y)); + } + } else { + this->grid.align(x, y) = point_n; + this->polygons[this->poly_n].append(point_n); + this->points[point_n] = CGAL_Nef_polyhedron2::Point(x, y); + point_n++; + } + } + if (this->polygons[this->poly_n].size() >= 3) { + add_edges(this->poly_n); + this->poly_n++; + } + else { + this->polygons.remove(this->poly_n); + } + } + } + + int merge(int p1, int p1e, int p2, int p2e) + { + for (int i = 1; i < this->polygons[p1].size(); i++) { + int j = (p1e + i) % this->polygons[p1].size(); + this->polygons[this->poly_n].append(this->polygons[p1][j]); + } + for (int i = 1; i < this->polygons[p2].size(); i++) { + int j = (p2e + i) % this->polygons[p2].size(); + this->polygons[this->poly_n].append(this->polygons[p2][j]); + } + del_poly(p1); + del_poly(p2); + add_edges(this->poly_n); + return this->poly_n++; + } + + void reduce() + { + QList<int> work_queue; + QHashIterator< int, QList<int> > it(polygons); + while (it.hasNext()) { + it.next(); + work_queue.append(it.key()); + } + while (!work_queue.isEmpty()) { + int poly1_n = work_queue.first(); + work_queue.removeFirst(); + if (!this->polygons.contains(poly1_n)) + continue; + for (int j = 1; j <= this->polygons[poly1_n].size(); j++) { + int a = this->polygons[poly1_n][j-1]; + int b = this->polygons[poly1_n][j % this->polygons[poly1_n].size()]; + if (a > b) { a = a^b; b = a^b; a = a^b; } + if (this->egde_to_poly[QPair<int,int>(a, b)].first != 0 && + this->egde_to_poly[QPair<int,int>(a, b)].second != 0) { + int poly2_n = this->egde_to_poly[QPair<int,int>(a, b)].first + + this->egde_to_poly[QPair<int,int>(a, b)].second - poly1_n; + int poly2_edge = -1; + for (int k = 1; k <= this->polygons[poly2_n].size(); k++) { + int c = this->polygons[poly2_n][k-1]; + int d = this->polygons[poly2_n][k % this->polygons[poly2_n].size()]; + if (c > d) { c = c^d; d = c^d; c = c^d; } + if (a == c && b == d) { + poly2_edge = k-1; + continue; + } + int poly3_n = this->egde_to_poly[QPair<int,int>(c, d)].first + + this->egde_to_poly[QPair<int,int>(c, d)].second - poly2_n; + if (poly3_n < 0) + continue; + if (poly3_n == poly1_n) + goto next_poly1_edge; + } + work_queue.append(merge(poly1_n, j-1, poly2_n, poly2_edge)); + goto next_poly1; + } + next_poly1_edge:; + } + next_poly1:; + } + } + + CGAL_Nef_polyhedron2 toNef() + { + CGAL_Nef_polyhedron2 N; + + QHashIterator< int, QList<int> > it(polygons); + while (it.hasNext()) { + it.next(); + std::list<CGAL_Nef_polyhedron2::Point> plist; + for (int j = 0; j < it.value().size(); j++) { + int p = it.value()[j]; + plist.push_back(points[p]); + } + N += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); + } + + return N; + } + }; + + PolyReducer pr(this); + // printf("Number of polygons before reduction: %d\n", pr.polygons.size()); + pr.reduce(); + // printf("Number of polygons after reduction: %d\n", pr.polygons.size()); + return CGAL_Nef_polyhedron(pr.toNef()); +#endif +#if 0 + // This is another experimental version. I should run faster than the above, + // is a lot simpler and has only one known weakness: Degenerate polygons, which + // get repaired by GLUTess, might trigger a CGAL crash here. The only + // known case for this is triangle-with-duplicate-vertex.dxf + // FIXME: If we just did a projection, we need to recreate the border! + if (this->polygons.size() > 0) assert(this->borders.size() > 0); + CGAL_Nef_polyhedron2 N; + Grid2d<CGAL_Nef_polyhedron2::Point> grid(GRID_COARSE); + + for (int i = 0; i < this->borders.size(); i++) { + std::list<CGAL_Nef_polyhedron2::Point> plist; + for (int j = 0; j < this->borders[i].size(); j++) { + double x = this->borders[i][j].x; + double y = this->borders[i][j].y; + CGAL_Nef_polyhedron2::Point p; + if (grid.has(x, y)) { + p = grid.data(x, y); + } else { + p = CGAL_Nef_polyhedron2::Point(x, y); + grid.data(x, y) = p; + } + plist.push_back(p); + } + // FIXME: If a border (path) has a duplicate vertex in dxf, + // the CGAL_Nef_polyhedron2 constructor will crash. + N ^= CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); + } + + return CGAL_Nef_polyhedron(N); + +#endif + } + else // not (this->is2d) + { + CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); + try { + CGAL_Polyhedron P; + CGAL_Build_PolySet builder(this); + P.delegate(builder); +#if 0 + std::cout << P; +#endif + CGAL_Nef_polyhedron3 N(P); + return CGAL_Nef_polyhedron(N); + } + catch (CGAL::Assertion_exception e) { + PRINTF("CGAL error: %s", e.what()); + CGAL::set_error_behaviour(old_behaviour); + return CGAL_Nef_polyhedron(); + } + CGAL::set_error_behaviour(old_behaviour); + } + return CGAL_Nef_polyhedron(); +======= return bbox; +>>>>>>> upstream/visitor } diff --git a/src/transform.cc b/src/transform.cc index f473f6a..885a7d6 100644 --- a/src/transform.cc +++ b/src/transform.cc @@ -61,7 +61,14 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti TransformNode *node = new TransformNode(inst); for (int i = 0; i < 16; i++) +<<<<<<< HEAD + node->m[i] = i % 5 == 0 ? 1.0 : 0.0; + for (int i = 16; i < 19; i++) + node->m[i] = -1; + node->m[19] = 1; +======= node->matrix[i] = i % 5 == 0 ? 1.0 : 0.0; +>>>>>>> upstream/visitor std::vector<std::string> argnames; std::vector<Expression*> argexpr; @@ -213,6 +220,37 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti } } } +<<<<<<< HEAD + else if (this->type == COLOR) + { + Value v = c.lookup_variable("c"); + if (v.type == Value::VECTOR) { + for (int i = 0; i < 4; i++) + node->matrix[16+i] = i < v.vec.size() ? v.vec[i]->num : 1.0; +// FIXME: Port to non-Qt +#if 0 + } else if (v.type == Value::STRING) { + QString colorname = v.text; + QColor color; + color.setNamedColor(colorname); + if (color.isValid()) { + node->matrix[16+0] = color.redF(); + node->matrix[16+1] = color.greenF(); + node->matrix[16+2] = color.blueF(); + } else { + PRINTF_NOCACHE("WARNING: Color name \"%s\" unknown. Please see",v.text.toUtf8().data()); + PRINTF_NOCACHE("WARNING: http://en.wikipedia.org/wiki/Web_colors"); + } +#endif + } + // FIXME: Only lookup alpha if color was set + Value alpha = c.lookup_variable("alpha"); + if (alpha.type == Value::NUMBER) { + node->m[16+3] = alpha.num; + } + } +======= +>>>>>>> upstream/visitor std::vector<AbstractNode *> evaluatednodes = inst->evaluateChildren(); node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); @@ -242,7 +280,31 @@ std::string TransformNode::toString() const std::string TransformNode::name() const { +<<<<<<< HEAD +<<<<<<< HEAD + return "transform"; +======= + if (dump_cache.isEmpty()) { + QString text; + if (m[16] >= 0 || m[17] >= 0 || m[18] >= 0) + text.sprintf("n%d: color([%g, %g, %g, %g])", idx, + m[16], m[17], m[18], m[19]); + else + text.sprintf("n%d: multmatrix([[%g, %g, %g, %g], [%g, %g, %g, %g], " + "[%g, %g, %g, %g], [%g, %g, %g, %g]])", idx, + m[0], m[4], m[ 8], m[12], + m[1], m[5], m[ 9], m[13], + m[2], m[6], m[10], m[14], + m[3], m[7], m[11], m[15]); + text = indent + text + " {\n"; + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; + } + return dump_cache; +======= return "transform"; +>>>>>>> upstream/visitor } void register_builtin_transform() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 509180e..1874669 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -57,6 +57,23 @@ if (NOT OPENCSG_INCLUDE_DIR) endif() include_directories(${OPENCSG_INCLUDE_DIR}) +# SDL (for OpenCSG on Linux & other platforms) +if (NOT $ENV{MACOSX_DEPLOY_DIR} STREQUAL "") + message(STATU "SDL not needed for Mac OSX") +else() + find_package(SDL REQUIRED) + if (NOT SDL_FOUND) + message(FATAL_ERROR "SDL not found. needed for OpenCSG testing on this platform") + else() + message(STATUS "SDL library found in " ${SDL_LIBRARY}) + message(STATUS "SDL header found in " ${SDL_INCLUDE_DIR}) + set(OPENGL_LIBRARY ${OPENGL_LIBRARY} ${SDL_LIBRARY}) + endif() +endif() +include_directories(${SDL_INCLUDE_DIR}) + +# GLEW + if (NOT $ENV{MACOSX_DEPLOY_DIR} STREQUAL "") set(GLEW_DIR "$ENV{MACOSX_DEPLOY_DIR}") endif() @@ -165,11 +182,24 @@ target_link_libraries(cgalpngtest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${ # # opencsgtest # +<<<<<<< HEAD +if (NOT $ENV{MACOSX_DEPLOY_DIR} STREQUAL "") + set(OFFSCREEN_SOURCE "OffscreenContext.mm") +else() + set(OFFSCREEN_SOURCE "OffscreenContext.cc") +endif() + +add_executable(opencsgtest opencsgtest.cc OffscreenView.cc ${OFFSCREEN_SOURCE} + ../src/cgal.cc ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc + ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/nef2dxf.cc + ../src/cgaladv_minkowski2.cc ../src/cgaladv_minkowski3.cc +======= add_executable(opencsgtest opencsgtest.cc OffscreenView.cc OffscreenContext.mm ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc ../src/CSGTermEvaluator.cc ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc ../src/CGALEvaluator.cc ../src/CGALCache.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc +>>>>>>> upstream/visitor ${COMMON_SOURCES}) set_target_properties(opencsgtest PROPERTIES COMPILE_FLAGS "-DENABLE_OPENCSG -DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") target_link_libraries(opencsgtest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENCSG_LIBRARY} ${GLEW_LIBRARY} ${COCOA_LIBRARY} ${OPENGL_LIBRARY}) @@ -202,6 +232,15 @@ add_cmdline_test(csgtexttest txt ${MINIMAL_FILES}) add_cmdline_test(csgtermtest txt ${MINIMAL_FILES}) # Add cgaltest tests to CTest +<<<<<<< HEAD +LIST(APPEND CGALTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/minimal/cube.scad) +LIST(APPEND CGALTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/minimal/sphere.scad) +LIST(APPEND CGALTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/minimal/cylinder.scad) +LIST(APPEND CGALTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/background-modifier.scad) +LIST(APPEND CGALTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/highlight-modifier.scad) +LIST(APPEND CGALTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) +======= +>>>>>>> upstream/visitor add_cmdline_test(cgaltest stl ${CGALTEST_FILES}) # Add cgalpngtest tests to CTest diff --git a/tests/FindGLEW.cmake b/tests/FindGLEW.cmake index e058e8c..edf590c 100644 --- a/tests/FindGLEW.cmake +++ b/tests/FindGLEW.cmake @@ -7,6 +7,9 @@ # GLEW_LIBRARY # +# a few lines of this file are based on the LGPL code found at +# http://openlibraries.org/browser/trunk/FindGLEW.cmake?rev=1383 + IF (WIN32) FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h $ENV{PROGRAMFILES}/GLEW/include @@ -20,14 +23,26 @@ IF (WIN32) ${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib DOC "The GLEW library") ELSE (WIN32) +<<<<<<< HEAD + MESSAGE( "-- GLEW_DIR value:" ${GLEW_DIR}) + FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h + PATHS /usr/include /usr/local/include + ${GLEW_DIR}/include +======= message("GLEW_DIR: " ${GLEW_DIR}) FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h PATHS ${GLEW_DIR}/include /usr/include /usr/local/include +>>>>>>> upstream/visitor NO_DEFAULT_PATH DOC "The directory where GL/glew.h resides") FIND_LIBRARY( GLEW_LIBRARY NAMES GLEW glew +<<<<<<< HEAD + PATHS /usr/lib /usr/local/lib + ${GLEW_DIR}/lib +======= PATHS ${GLEW_DIR}/lib /usr/lib /usr/local/lib +>>>>>>> upstream/visitor NO_DEFAULT_PATH DOC "The GLEW library") ENDIF (WIN32) diff --git a/tests/OffscreenContext.cc b/tests/OffscreenContext.cc new file mode 100644 index 0000000..0795fe7 --- /dev/null +++ b/tests/OffscreenContext.cc @@ -0,0 +1,139 @@ +#include "OffscreenContext.h" + +// see http://www.gamedev.net/topic/552607-conflict-between-glew-and-sdl/ +#define NO_SDL_GLEXT +#include <GL/glew.h> + +#define GL_GLEXT_PROTOTYPES +#include <GL/gl.h> +#include <GL/glext.h> + +//#include <GL/gl.h> +//#include <GL/glu.h> // for gluCheckExtension +#include <SDL.h> + +// Simple error reporting macros to help keep the sample code clean +#define REPORT_ERROR_AND_EXIT(desc) { std::cout << desc << "\n"; return false; } +#define NULL_ERROR_EXIT(test, desc) { if (!test) REPORT_ERROR_AND_EXIT(desc); } + +struct OffscreenContext +{ + int width; + int height; + GLuint fbo; + GLuint colorbo; + GLuint depthbo; +}; + + +OffscreenContext *create_offscreen_context(int w, int h) +{ + OffscreenContext *ctx = new OffscreenContext; + ctx->width = w; + ctx->height = h; + + // dummy window + SDL_Init(SDL_INIT_VIDEO); + SDL_SetVideoMode(256,256,32,SDL_OPENGL); + + // must come after openGL context init (done by dummy window) + // but must also come before various EXT calls + glewInit(); + +/* + // Test if framebuffer objects are supported + const GLubyte* strExt = glGetString(GL_EXTENSIONS); + GLboolean fboSupported = gluCheckExtension((const GLubyte*)"GL_EXT_framebuffer_object", strExt); + if (!fboSupported) + REPORT_ERROR_AND_EXIT("Your system does not support framebuffer extension - unable to render scene"); + + printf("%i\n", (int)glGenFramebuffersEXT); + GLuint fbo; + //ctx->fbo = 0; + glGenFramebuffersEXT(1, &fbo); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); + REPORTGLERROR("binding framebuffer"); + + + GLuint renderBuffer = 0; + GLuint depthBuffer = 0; + // Depth buffer to use for depth testing - optional if you're not using depth testing + glGenRenderbuffersEXT(1, &depthBuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, w, h); + REPORTGLERROR("creating depth render buffer"); + + // Render buffer to use for imaging + glGenRenderbuffersEXT(1, &renderBuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBuffer); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, w, h); + REPORTGLERROR("creating color render buffer"); + + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, renderBuffer); + REPORTGLERROR("specifying color render buffer"); + + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != + GL_FRAMEBUFFER_COMPLETE_EXT) + REPORT_ERROR_AND_EXIT("Problem with OpenGL framebuffer after specifying color render buffer."); + + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, depthBuffer); + REPORTGLERROR("specifying depth render buffer"); + + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != + GL_FRAMEBUFFER_COMPLETE_EXT) + REPORT_ERROR_AND_EXIT("Problem with OpenGL framebuffer after specifying depth render buffer."); +*/ + + return ctx; +} + +bool teardown_offscreen_context(OffscreenContext *ctx) +{ + // "un"bind my FBO +// glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + + /* + * Cleanup + */ + return true; +} + +void write_targa(const char *filename, GLubyte *pixels, int width, int height) +{ + FILE *f = fopen( filename, "w" ); + int y; + if (f) { + GLubyte header[] = { + 00,00,02, 00,00,00, 00,00,00, 00,00,00, + 0xff & width, 0xff & width >> 8, + 0xff & height, 0xff & height >> 8, + 32, 0x20 }; // next-to-last = bit depth + fwrite( header, sizeof(header), 1, f); + for (y=height-1; y>=0; y--) + fwrite( pixels + y*width*4, 4, width, f); + fclose(f); + } +} + +bool save_framebuffer(OffscreenContext *ctx, const char *filename) +{ + /* + * Extract the resulting rendering as an image + */ + + int samplesPerPixel = 4; // R, G, B and A + + GLubyte pixels[ ctx->width * ctx->height * samplesPerPixel ]; + glReadPixels(0, 0, ctx->width, ctx->height, GL_BGRA, GL_UNSIGNED_BYTE, pixels); + printf("writing %s\n",filename); + write_targa(filename,pixels,ctx->width, ctx->height); + + return true; +} + +void bind_offscreen_context(OffscreenContext *ctx) +{ +// glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->fbo); +} diff --git a/tests/OffscreenContext.h b/tests/OffscreenContext.h index 0300bcb..f1c7123 100644 --- a/tests/OffscreenContext.h +++ b/tests/OffscreenContext.h @@ -1,7 +1,13 @@ #ifndef OFFSCREENCONTEXT_H_ #define OFFSCREENCONTEXT_H_ +#ifdef Q_WS_MAC #include <OpenGL/OpenGL.h> +#else +#include <GL/glew.h> +#include <GL/gl.h> +#endif + #include <iostream> // for error output #define REPORTGLERROR(task) { GLenum tGLErr = glGetError(); if (tGLErr != GL_NO_ERROR) { std::cout << "OpenGL error " << tGLErr << " while " << task << "\n"; } } diff --git a/tests/OffscreenView.cc b/tests/OffscreenView.cc index 447a78c..8a4b57d 100644 --- a/tests/OffscreenView.cc +++ b/tests/OffscreenView.cc @@ -1,8 +1,11 @@ #include <GL/glew.h> #include "OffscreenView.h" #include <opencsg.h> -#include "Renderer.h" +#include "renderer.h" #include <math.h> +#include <stdio.h> +#include <string.h> +#include <cstdlib> #define FAR_FAR_AWAY 100000.0 diff --git a/tests/csgtermtest.cc b/tests/csgtermtest.cc index 7c37b0a..f23ec70 100644 --- a/tests/csgtermtest.cc +++ b/tests/csgtermtest.cc @@ -111,7 +111,7 @@ int main(int argc, char **argv) AbstractModule *root_module; ModuleInstantiation root_inst; - AbstractNode *root_node; + const AbstractNode *root_node; QFileInfo fileInfo(filename); handle_dep(filename); @@ -144,11 +144,17 @@ int main(int argc, char **argv) // cout << tree.getString(*root_node) << "\n"; +<<<<<<< HEAD + CSGTermEvaluator evaluator(tree); + vector<CSGTerm*> empty = vector<CSGTerm*>(); + CSGTerm *root_term = evaluator.evaluateCSGTerm(*root_node, empty, empty); +======= vector<CSGTerm*> highlights; vector<CSGTerm*> background; PolySetEvaluator psevaluator(tree); CSGTermEvaluator evaluator(tree, &psevaluator); CSGTerm *root_term = evaluator.evaluateCSGTerm(*root_node, highlights, background); +>>>>>>> upstream/visitor // cout << "Stored terms: " << evaluator.stored_term.size() << "\n"; // for (map<int, class CSGTerm*>::iterator iter = evaluator.stored_term.begin(); diff --git a/tests/opencsgtest.cc b/tests/opencsgtest.cc index 59501a0..98e1037 100644 --- a/tests/opencsgtest.cc +++ b/tests/opencsgtest.cc @@ -235,8 +235,8 @@ int main(int argc, char *argv[]) OpenCSGRenderer opencsgRenderer(csgInfo.root_chain, csgInfo.highlights_chain, csgInfo.background_chain, csgInfo.glview->shaderinfo); ThrownTogetherRenderer thrownTogetherRenderer(csgInfo.root_chain, csgInfo.highlights_chain, csgInfo.background_chain); -// csgInfo.glview->setRenderer(&thrownTogetherRenderer); - csgInfo.glview->setRenderer(&opencsgRenderer); + csgInfo.glview->setRenderer(&thrownTogetherRenderer); +// csgInfo.glview->setRenderer(&opencsgRenderer); csgInfo.glview->paintGL(); |