diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/CMakeLists.txt | 22 | ||||
| -rw-r--r-- | tests/OffscreenContext.h | 13 | ||||
| -rw-r--r-- | tests/OffscreenContext.mm | 198 | ||||
| -rw-r--r-- | tests/OffscreenView.cc | 232 | ||||
| -rw-r--r-- | tests/OffscreenView.h | 34 | ||||
| -rw-r--r-- | tests/cgaltest.cc | 16 | ||||
| -rw-r--r-- | tests/opencsgtest.cc | 169 | 
7 files changed, 522 insertions, 162 deletions
| diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c5c1104..74d3df2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,6 +12,11 @@ endif()  # Build test apps  # +# Mac OS X +if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") +  FIND_LIBRARY(COCOA_LIBRARY Cocoa) +endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") +  # Qt4  find_package(OpenGL)  find_package(Qt4 COMPONENTS QtCore QtGui QtOpenGL REQUIRED) @@ -98,7 +103,7 @@ set(COMMON_SOURCES    ../src/progress.cc     ../src/nodedumper.cc     ../src/traverser.cc  -  ../src/PolySetRenderer.cc  +  ../src/PolySetEvaluator.cc     ../src/Tree.cc    ${FLEX_OpenSCADlexer_OUTPUTS}    ${BISON_OpenSCADparser_OUTPUTS}) @@ -118,7 +123,7 @@ target_link_libraries(csgtexttest ${QT_LIBRARIES} ${OPENGL_LIBRARY})  #  # csgtermtest  # -add_executable(csgtermtest csgtermtest.cc ../src/CSGTermRenderer.cc ${COMMON_SOURCES}) +add_executable(csgtermtest csgtermtest.cc ../src/CSGTermEvaluator.cc ${COMMON_SOURCES})  target_link_libraries(csgtermtest ${QT_LIBRARIES} ${OPENGL_LIBRARY})  if (NOT $ENV{MACOSX_DEPLOY_DIR} STREQUAL "") @@ -131,8 +136,8 @@ include_directories(${CGAL_INCLUDE_DIRS})  #  # cgaltest  # -add_executable(cgaltest cgaltest.cc ../src/CSGTermRenderer.cc ../src/CGALRenderer.cc -                        ../src/PolySetCGALRenderer.cc ../src/qhash.cc ../src/nef2dxf.cc +add_executable(cgaltest cgaltest.cc ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc +                        ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/nef2dxf.cc                          ../src/cgaladv_minkowski2.cc ../src/cgaladv_minkowski3.cc ${COMMON_SOURCES})  set_target_properties(cgaltest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}")  target_link_libraries(cgaltest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENGL_LIBRARY}) @@ -140,14 +145,13 @@ target_link_libraries(cgaltest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_  #  # opencsgtest  # -QT4_WRAP_CPP(MOC_SRC_opencsgtest ../src/GLView.h) -add_executable(opencsgtest opencsgtest.cc ${MOC_SRC_opencsgtest} ../src/glview.cc -                           ../src/render-opencsg.cc ../src/CSGTermRenderer.cc ../src/CGALRenderer.cc -                           ../src/PolySetCGALRenderer.cc ../src/qhash.cc ../src/nef2dxf.cc +add_executable(opencsgtest opencsgtest.cc OffscreenView.cc OffscreenContext.mm +                           ../src/opencsgrenderer.cc ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc +                           ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/nef2dxf.cc                             ../src/cgaladv_minkowski2.cc ../src/cgaladv_minkowski3.cc                             ${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} ${OPENGL_LIBRARY}) +target_link_libraries(opencsgtest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENCSG_LIBRARY} ${GLEW_LIBRARY} ${COCOA_LIBRARY} ${OPENGL_LIBRARY})  #  # This functions adds cmd-line tests given files. diff --git a/tests/OffscreenContext.h b/tests/OffscreenContext.h new file mode 100644 index 0000000..59b6e2d --- /dev/null +++ b/tests/OffscreenContext.h @@ -0,0 +1,13 @@ +#ifndef OFFSCREENCONTEXT_H_ +#define OFFSCREENCONTEXT_H_ + +#include <OpenGL/OpenGL.h> +#include <iostream>         // for error output + +#define REPORTGLERROR(task) { GLenum tGLErr = glGetError(); if (tGLErr != GL_NO_ERROR) { std::cout << "OpenGL error " << tGLErr << " while " << task << "\n"; } } + +struct OffscreenContext *create_offscreen_context(int w, int h); +bool teardown_offscreen_context(OffscreenContext *ctx); +bool save_framebuffer(OffscreenContext *ctx, const char *filename); + +#endif diff --git a/tests/OffscreenContext.mm b/tests/OffscreenContext.mm new file mode 100644 index 0000000..7ff7772 --- /dev/null +++ b/tests/OffscreenContext.mm @@ -0,0 +1,198 @@ +#include "OffscreenContext.h" + +#import <OpenGL/OpenGL.h> +#import <OpenGL/glu.h>      // for gluCheckExtension +#import <AppKit/AppKit.h>   // for NSOpenGL... + +// 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 +{ +  NSOpenGLContext *openGLContext; +  NSAutoreleasePool *pool; +  int width; +  int height; +}; + + +OffscreenContext *create_offscreen_context(int w, int h) +{ +  OffscreenContext *ctx = new OffscreenContext; +  ctx->width = w; +  ctx->height = h; + +  ctx->pool = [NSAutoreleasePool new]; + +  /* +   * Create an OpenGL context just so that OpenGL calls will work. I'm not  +   using it for actual rendering. +  */ +                                    +  NSOpenGLPixelFormatAttribute    attributes[] = { +    NSOpenGLPFAPixelBuffer, +    NSOpenGLPFANoRecovery, +    NSOpenGLPFAAccelerated, +    NSOpenGLPFADepthSize, 24, +    (NSOpenGLPixelFormatAttribute) 0 +  }; +  NSOpenGLPixelFormat*            pixFormat = [[[NSOpenGLPixelFormat  +                                                 alloc] initWithAttributes:attributes] autorelease]; +  // Create the OpenGL context to render with (with color and depth buffers) +  ctx->openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixFormat  +                   shareContext:nil]; +  NULL_ERROR_EXIT(ctx->openGLContext, "Unable to create NSOpenGLContext"); + +  [ctx->openGLContext makeCurrentContext]; + +  /* +   * 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"); +  /* +   * Create an FBO +   */ +  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"); +  GLuint  fbo = 0; +  glGenFramebuffersEXT(1, &fbo); +  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); +  REPORTGLERROR("binding framebuffer"); + +  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 +   */ +  [ctx->openGLContext clearDrawable]; +  [ctx->openGLContext release]; + +  [ctx->pool release]; +  return true; +} + +bool save_framebuffer(OffscreenContext *ctx, const char *filename) +{ +  /* +   * Extract the resulting rendering as an image +   */ + +  int samplesPerPixel = 4; // R, G, B and A +  int rowBytes = samplesPerPixel * ctx->width; +  char* bufferData = (char*)malloc(rowBytes * ctx->height); +  if (!bufferData) { +    std::cerr << "Unable to allocate buffer for image extraction."; +    return 1; +  } +  glReadPixels(0, 0, ctx->width, ctx->height, GL_BGRA, GL_UNSIGNED_BYTE,  +               bufferData); +  REPORTGLERROR("reading pixels from framebuffer"); +   +  // Flip it vertically - images read from OpenGL buffers are upside-down +  char* flippedBuffer = (char*)malloc(rowBytes * ctx->height); +  if (!flippedBuffer) { +    std::cout << "Unable to allocate flipped buffer for corrected image."; +    return 1; +  } +  for (int i = 0 ; i < ctx->height ; i++) { +    bcopy(bufferData + i * rowBytes, flippedBuffer + (ctx->height - i - 1) *  +          rowBytes, rowBytes); +  } + +  /* +   * Output the image to a file +   */ +  CGColorSpaceRef colorSpace =  +    CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); +  CGBitmapInfo bitmapInfo = kCGImageAlphaNoneSkipFirst |  +    kCGBitmapByteOrder32Little;  // XRGB Little Endian +  int bitsPerComponent = 8; +  CGContextRef contextRef = CGBitmapContextCreate(flippedBuffer, +                                                  ctx->width, ctx->height, bitsPerComponent, rowBytes,  +                                                  colorSpace, bitmapInfo); +  if (!contextRef) { +    std::cerr << "Unable to create CGContextRef."; +    return false; +  } + +  CGImageRef imageRef = CGBitmapContextCreateImage(contextRef); +  if (!imageRef) { +    std::cerr <<  "Unable to create CGImageRef."; +    return false; +  } +  Boolean isDirectory = false; +  CFStringRef fname = CFStringCreateWithCString(kCFAllocatorDefault, filename, kCFStringEncodingUTF8); +  CFURLRef fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, +                                                   fname, kCFURLPOSIXPathStyle, isDirectory); +  if (!fileURL) { +    std::cerr << "Unable to create file URL ref."; +    return false; +  } +  CFIndex                 fileImageIndex = 1; +  CFMutableDictionaryRef  fileDict       = NULL; +  CFStringRef             fileUTType     = kUTTypeJPEG; +  // Create an image destination opaque reference for authoring an image file +  CGImageDestinationRef imageDest = CGImageDestinationCreateWithURL(fileURL,  +                                                                    fileUTType,  +                                                                    fileImageIndex,  +                                                                    fileDict); +  if (!imageDest) { +    std::cerr <<  "Unable to create CGImageDestinationRef."; +    return false; +  } +  CFIndex capacity = 1; +  CFMutableDictionaryRef imageProps =  +    CFDictionaryCreateMutable(kCFAllocatorDefault,  +                              capacity, +                              &kCFTypeDictionaryKeyCallBacks, +                              &kCFTypeDictionaryValueCallBacks); +  CGImageDestinationAddImage(imageDest, imageRef, imageProps); +  CGImageDestinationFinalize(imageDest); + +  free(flippedBuffer); +  free(bufferData); +  CFRelease(imageDest); +  CFRelease(fileURL); +  CFRelease(fname); +  CFRelease(imageProps); +  CGColorSpaceRelease( colorSpace ); +  CGImageRelease(imageRef); +  return true; +} diff --git a/tests/OffscreenView.cc b/tests/OffscreenView.cc new file mode 100644 index 0000000..b7ee8c7 --- /dev/null +++ b/tests/OffscreenView.cc @@ -0,0 +1,232 @@ +#include <GL/glew.h> +#include "OffscreenView.h" +#include "Renderer.h" +#include "OffscreenContext.h" +#include <math.h> + +#define FAR_FAR_AWAY 100000.0 + +OffscreenView::OffscreenView(size_t width, size_t height) +	: orthomode(false), showaxes(false), showfaces(false), showedges(false), viewer_distance(500) +{ +  this->ctx = create_offscreen_context(width, height); +	initializeGL(); +	resizeGL(width, height); +} + +OffscreenView::~OffscreenView() +{ +	teardown_offscreen_context(this->ctx); +} + +void OffscreenView::setRenderer(Renderer* r) +{ +	this->renderer = r; +} + +void OffscreenView::initializeGL() +{ +	glEnable(GL_DEPTH_TEST); +	glDepthRange(-FAR_FAR_AWAY, +FAR_FAR_AWAY); + +	glEnable(GL_BLEND); +	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +	GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0}; +	GLfloat light_position0[] = {-1.0, -1.0, +1.0, 0.0}; +	GLfloat light_position1[] = {+1.0, +1.0, -1.0, 0.0}; + +	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); +	glLightfv(GL_LIGHT0, GL_POSITION, light_position0); +	glEnable(GL_LIGHT0); +	glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); +	glLightfv(GL_LIGHT1, GL_POSITION, light_position1); +	glEnable(GL_LIGHT1); +	glEnable(GL_LIGHTING); +	glEnable(GL_NORMALIZE); + +	glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); +	glEnable(GL_COLOR_MATERIAL); + +#ifdef ENABLE_OPENCSG +	const char *openscad_disable_gl20_env = getenv("OPENSCAD_DISABLE_GL20"); +	if (openscad_disable_gl20_env && !strcmp(openscad_disable_gl20_env, "0")) +		openscad_disable_gl20_env = NULL; +	if (glewIsSupported("GL_VERSION_2_0") && openscad_disable_gl20_env == NULL) +	{ +		const char *vs_source = +			"uniform float xscale, yscale;\n" +			"attribute vec3 pos_b, pos_c;\n" +			"attribute vec3 trig, mask;\n" +			"varying vec3 tp, tr;\n" +			"varying float shading;\n" +			"void main() {\n" +			"  vec4 p0 = gl_ModelViewProjectionMatrix * gl_Vertex;\n" +			"  vec4 p1 = gl_ModelViewProjectionMatrix * vec4(pos_b, 1.0);\n" +			"  vec4 p2 = gl_ModelViewProjectionMatrix * vec4(pos_c, 1.0);\n" +			"  float a = distance(vec2(xscale*p1.x/p1.w, yscale*p1.y/p1.w), vec2(xscale*p2.x/p2.w, yscale*p2.y/p2.w));\n" +			"  float b = distance(vec2(xscale*p0.x/p0.w, yscale*p0.y/p0.w), vec2(xscale*p1.x/p1.w, yscale*p1.y/p1.w));\n" +			"  float c = distance(vec2(xscale*p0.x/p0.w, yscale*p0.y/p0.w), vec2(xscale*p2.x/p2.w, yscale*p2.y/p2.w));\n" +			"  float s = (a + b + c) / 2.0;\n" +			"  float A = sqrt(s*(s-a)*(s-b)*(s-c));\n" +			"  float ha = 2.0*A/a;\n" +			"  gl_Position = p0;\n" +			"  tp = mask * ha;\n" +			"  tr = trig;\n" +			"  vec3 normal, lightDir;\n" +			"  normal = normalize(gl_NormalMatrix * gl_Normal);\n" +			"  lightDir = normalize(vec3(gl_LightSource[0].position));\n" +			"  shading = abs(dot(normal, lightDir));\n" +			"}\n"; + +		const char *fs_source = +			"uniform vec4 color1, color2;\n" +			"varying vec3 tp, tr, tmp;\n" +			"varying float shading;\n" +			"void main() {\n" +			"  gl_FragColor = vec4(color1.r * shading, color1.g * shading, color1.b * shading, color1.a);\n" +			"  if (tp.x < tr.x || tp.y < tr.y || tp.z < tr.z)\n" +			"    gl_FragColor = color2;\n" +			"}\n"; + +		GLuint vs = glCreateShader(GL_VERTEX_SHADER); +		glShaderSource(vs, 1, (const GLchar**)&vs_source, NULL); +		glCompileShader(vs); + +		GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); +		glShaderSource(fs, 1, (const GLchar**)&fs_source, NULL); +		glCompileShader(fs); + +		GLuint edgeshader_prog = glCreateProgram(); +		glAttachShader(edgeshader_prog, vs); +		glAttachShader(edgeshader_prog, fs); +		glLinkProgram(edgeshader_prog); + +		shaderinfo[0] = edgeshader_prog; +		shaderinfo[1] = glGetUniformLocation(edgeshader_prog, "color1"); +		shaderinfo[2] = glGetUniformLocation(edgeshader_prog, "color2"); +		shaderinfo[3] = glGetAttribLocation(edgeshader_prog, "trig"); +		shaderinfo[4] = glGetAttribLocation(edgeshader_prog, "pos_b"); +		shaderinfo[5] = glGetAttribLocation(edgeshader_prog, "pos_c"); +		shaderinfo[6] = glGetAttribLocation(edgeshader_prog, "mask"); +		shaderinfo[7] = glGetUniformLocation(edgeshader_prog, "xscale"); +		shaderinfo[8] = glGetUniformLocation(edgeshader_prog, "yscale"); + +		GLenum err = glGetError(); +		if (err != GL_NO_ERROR) { +			fprintf(stderr, "OpenGL Error: %s\n", gluErrorString(err)); +		} + +		GLint status; +		glGetProgramiv(edgeshader_prog, GL_LINK_STATUS, &status); +		if (status == GL_FALSE) { +			int loglen; +			char logbuffer[1000]; +			glGetProgramInfoLog(edgeshader_prog, sizeof(logbuffer), &loglen, logbuffer); +			fprintf(stderr, "OpenGL Program Linker Error:\n%.*s", loglen, logbuffer); +		} else { +			int loglen; +			char logbuffer[1000]; +			glGetProgramInfoLog(edgeshader_prog, sizeof(logbuffer), &loglen, logbuffer); +			if (loglen > 0) { +				fprintf(stderr, "OpenGL Program Link OK:\n%.*s", loglen, logbuffer); +			} +			glValidateProgram(edgeshader_prog); +			glGetProgramInfoLog(edgeshader_prog, sizeof(logbuffer), &loglen, logbuffer); +			if (loglen > 0) { +				fprintf(stderr, "OpenGL Program Validation results:\n%.*s", loglen, logbuffer); +			} +		} +	} +#endif /* ENABLE_OPENCSG */ +} + +void OffscreenView::resizeGL(int w, int h) +{ +#ifdef ENABLE_OPENCSG +	shaderinfo[9] = w; +	shaderinfo[10] = h; +#endif +	glViewport(0, 0, w, h); +	w_h_ratio = sqrt((double)w / (double)h); +	setupPerspective(); +} + +void OffscreenView::setupPerspective() +{ +	glMatrixMode(GL_PROJECTION); +	glLoadIdentity(); +	glFrustum(-w_h_ratio, +w_h_ratio, -(1/w_h_ratio), +(1/w_h_ratio), +10.0, +FAR_FAR_AWAY); +} + +void OffscreenView::setupOrtho(double distance, bool offset) +{ +	glMatrixMode(GL_PROJECTION); +	glLoadIdentity(); +	if(offset) +		glTranslated(-0.8, -0.8, 0); +	double l = distance/10; +	glOrtho(-w_h_ratio*l, +w_h_ratio*l, +			-(1/w_h_ratio)*l, +(1/w_h_ratio)*l, +			-FAR_FAR_AWAY, +FAR_FAR_AWAY); +} + +void OffscreenView::paintGL() +{ +	glEnable(GL_LIGHTING); + +	if (orthomode) +		setupOrtho(viewer_distance); + +	glMatrixMode(GL_MODELVIEW); +	glLoadIdentity(); + +	glClearColor(1.0, 1.0, 0.92, 0.0); + +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + +	gluLookAt(0.0, -viewer_distance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); + +//	glTranslated(object_trans_x, object_trans_y, object_trans_z); + +	// glRotated(object_rot_x, 1.0, 0.0, 0.0); +	// glRotated(object_rot_y, 0.0, 1.0, 0.0); +	// glRotated(object_rot_z, 0.0, 0.0, 1.0); + +	// Large gray axis cross inline with the model +  // FIXME: This is always gray - adjust color to keep contrast with background +	if (showaxes) +	{ +		glLineWidth(1); +		glColor3d(0.5, 0.5, 0.5); +		glBegin(GL_LINES); +		double l = viewer_distance/10; +		glVertex3d(-l, 0, 0); +		glVertex3d(+l, 0, 0); +		glVertex3d(0, -l, 0); +		glVertex3d(0, +l, 0); +		glVertex3d(0, 0, -l); +		glVertex3d(0, 0, +l); +		glEnd(); +	} + +	glDepthFunc(GL_LESS); +	glCullFace(GL_BACK); +	glDisable(GL_CULL_FACE); + +	glLineWidth(2); +	glColor3d(1.0, 0.0, 0.0); + +	if (this->renderer) { +#if defined(ENABLE_MDI) && defined(ENABLE_OPENCSG) +		// FIXME: This belongs in the OpenCSG renderer, but it doesn't know about this ID yet +		OpenCSG::setContext(this->opencsg_id); +#endif +		this->renderer->draw(showfaces, showedges); +	} +} + +bool OffscreenView::save(const char *filename) +{ +	return save_framebuffer(this->ctx, filename); +} diff --git a/tests/OffscreenView.h b/tests/OffscreenView.h new file mode 100644 index 0000000..6531bcf --- /dev/null +++ b/tests/OffscreenView.h @@ -0,0 +1,34 @@ +#ifndef OFFSCREENVIEW_H_ +#define OFFSCREENVIEW_H_ + +#include "OffscreenContext.h" +#include <stdint.h> + +class OffscreenView +{ +public: +	OffscreenView(size_t width, size_t height); +	~OffscreenView(); +	void setRenderer(class Renderer* r); + +	void initializeGL(); +	void resizeGL(int w, int h); +	void setupPerspective(); +	void setupOrtho(double distance,bool offset=false); +	void paintGL(); +	bool save(const char *filename); + +	GLint shaderinfo[11]; +private: +	Renderer *renderer; +	class OffscreenContext *ctx; +	double w_h_ratio; + +	bool orthomode; +	bool showaxes; +	bool showfaces; +	bool showedges; +	float viewer_distance; +}; + +#endif diff --git a/tests/cgaltest.cc b/tests/cgaltest.cc index 1466837..df03a43 100644 --- a/tests/cgaltest.cc +++ b/tests/cgaltest.cc @@ -32,8 +32,8 @@  #include "export.h"  #include "builtin.h"  #include "Tree.h" -#include "CGALRenderer.h" -#include "PolySetCGALRenderer.h" +#include "CGALEvaluator.h" +#include "PolySetCGALEvaluator.h"  #include <QApplication>  #include <QFile> @@ -72,9 +72,9 @@ void cgalTree(Tree &tree)  {  	assert(tree.root()); -	CGALRenderer renderer(cache, tree); -	Traverser render(renderer, *tree.root(), Traverser::PRE_AND_POSTFIX); -	render.execute(); +	CGALEvaluator evaluator(cache, tree); +	Traverser evaluate(evaluator, *tree.root(), Traverser::PRE_AND_POSTFIX); +	evaluate.execute();  }  int main(int argc, char **argv) @@ -163,10 +163,10 @@ int main(int argc, char **argv)  	Tree tree(root_node);  	QHash<std::string, CGAL_Nef_polyhedron> cache; -	CGALRenderer cgalrenderer(cache, tree); - 	PolySetCGALRenderer psrenderer(cgalrenderer); +	CGALEvaluator cgalevaluator(cache, tree); + 	PolySetCGALEvaluator psevaluator(cgalevaluator); -	CGAL_Nef_polyhedron N = cgalrenderer.renderCGALMesh(*root_node); +	CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node);  	QDir::setCurrent(original_path.absolutePath());  	QTextStream outstream(stdout); diff --git a/tests/opencsgtest.cc b/tests/opencsgtest.cc index 9381c54..4d69650 100644 --- a/tests/opencsgtest.cc +++ b/tests/opencsgtest.cc @@ -5,15 +5,15 @@  #include "module.h"  #include "polyset.h"  #include "Tree.h" -#include "CSGTermRenderer.h" -#include "CGALRenderer.h" -#include "PolySetCGALRenderer.h" +#include "CSGTermEvaluator.h" +#include "CGALEvaluator.h" +#include "PolySetCGALEvaluator.h" + +#include "OpenCSGRenderer.h"  #include "csgterm.h" -#include "render-opencsg.h"  #include <GL/glew.h> -#include "GLView.h" -#include "mainwindow.h" +#include "OffscreenView.h"  #include <QApplication>  #include <QFile> @@ -56,130 +56,9 @@ struct CsgInfo  	CSGChain *highlights_chain;  	std::vector<CSGTerm*> background_terms;  	CSGChain *background_chain; -	GLView *glview; +	OffscreenView *glview;  }; -static void renderGLThrownTogetherChain(CSGChain *chain, bool highlight, bool background, bool fberror) -{ -	glDepthFunc(GL_LEQUAL); -	QHash<QPair<PolySet*,double*>,int> polySetVisitMark; -	bool showEdges = false; -	for (int i = 0; i < chain->polysets.size(); i++) { -		if (polySetVisitMark[QPair<PolySet*,double*>(chain->polysets[i], chain->matrices[i])]++ > 0) -			continue; -		double *m = chain->matrices[i]; -		glPushMatrix(); -		glMultMatrixd(m); -		int csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; -		if (highlight) { -			chain->polysets[i]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m); -			if (showEdges) { -				glDisable(GL_LIGHTING); -				chain->polysets[i]->render_edges(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20)); -				glEnable(GL_LIGHTING); -			} -		} else if (background) { -			chain->polysets[i]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m); -			if (showEdges) { -				glDisable(GL_LIGHTING); -				chain->polysets[i]->render_edges(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10)); -				glEnable(GL_LIGHTING); -			} -		} else if (fberror) { -			if (highlight) { -				chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 20), m); -			} else if (background) { -				chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 10), m); -			} else { -				chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); -			} -		} else if (m[16] >= 0 || m[17] >= 0 || m[18] >= 0 || m[19] >= 0) { -			glColor4d(m[16], m[17], m[18], m[19]); -			chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); -			if (showEdges) { -				glDisable(GL_LIGHTING); -				glColor4d((m[16]+1)/2, (m[17]+1)/2, (m[18]+1)/2, 1.0); -				chain->polysets[i]->render_edges(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode)); -				glEnable(GL_LIGHTING); -			} -		} else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) { -			chain->polysets[i]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), m); -			if (showEdges) { -				glDisable(GL_LIGHTING); -				chain->polysets[i]->render_edges(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode)); -				glEnable(GL_LIGHTING); -			} -		} else { -			chain->polysets[i]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), m); -			if (showEdges) { -				glDisable(GL_LIGHTING); -				chain->polysets[i]->render_edges(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode)); -				glEnable(GL_LIGHTING); -			} -		} -		glPopMatrix(); -	} -} - -static void renderGLThrownTogether(void *vp) -{ -	CsgInfo *csgInfo = (CsgInfo *)vp; -	if (csgInfo->root_chain) { -		glEnable(GL_CULL_FACE); -		glCullFace(GL_BACK); -		renderGLThrownTogetherChain(csgInfo->root_chain, false, false, false); -		glCullFace(GL_FRONT); -		glColor3ub(255, 0, 255); -		renderGLThrownTogetherChain(csgInfo->root_chain, false, false, true); -		glDisable(GL_CULL_FACE); -	} -	if (csgInfo->background_chain) -		renderGLThrownTogetherChain(csgInfo->background_chain, false, true, false); -	if (csgInfo->highlights_chain) -		renderGLThrownTogetherChain(csgInfo->highlights_chain, true, false, false); -} - -static void renderGLviaOpenCSG(void *vp) -{ -	CsgInfo *csgInfo = (CsgInfo *)vp; - -	if (csgInfo->root_chain) { -		glEnable(GL_CULL_FACE); -		glCullFace(GL_BACK); -		glDepthFunc(GL_LEQUAL); -		QHash<QPair<PolySet*,double*>,int> polySetVisitMark; -		bool showEdges = false; -		int i = 1; -		double *m = csgInfo->root_chain->matrices[i]; -		glPushMatrix(); -		glMultMatrixd(m); -		int csgmode = csgInfo->root_chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; -		csgInfo->root_chain->polysets[i]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), m); -		glPopMatrix(); -	} - -	// static bool glew_initialized = false; -	// if (!glew_initialized) { -	// 	glew_initialized = true; -	// 	glewInit(); -	// } -#ifdef ENABLE_MDI -	OpenCSG::setContext(csgInfo->glview->opencsg_id); -#endif -	if (csgInfo->root_chain) { -		renderCSGChainviaOpenCSG(csgInfo->root_chain, NULL, false, false); -		GLint *shaderinfo = csgInfo->glview->shaderinfo; -		if (!shaderinfo[0]) shaderinfo = NULL; -		renderCSGChainviaOpenCSG(csgInfo->root_chain, NULL, false, false); -		if (csgInfo->background_chain) { -			renderCSGChainviaOpenCSG(csgInfo->background_chain, NULL, false, true); -		} -		if (csgInfo->highlights_chain) { -			renderCSGChainviaOpenCSG(csgInfo->highlights_chain, NULL, true, false); -		} -	} -} -  int main(int argc, char *argv[])  {  	if (argc != 2) { @@ -267,10 +146,10 @@ int main(int argc, char *argv[])  	Tree tree(root_node);  	QHash<std::string, CGAL_Nef_polyhedron> cache; -	CGALRenderer cgalrenderer(cache, tree); -	PolySetCGALRenderer psrenderer(cgalrenderer); -	CSGTermRenderer renderer(tree); -	CSGTerm *root_raw_term = renderer.renderCSGTerm(*root_node, NULL, NULL); +	CGALEvaluator cgalevaluator(cache, tree); +	PolySetCGALEvaluator psevaluator(cgalevaluator); +	CSGTermEvaluator evaluator(tree); +	CSGTerm *root_raw_term = evaluator.evaluateCSGTerm(*root_node, NULL, NULL);  	if (!root_raw_term) {  		cerr << "Error: CSG generation failed! (no top level object found)\n"; @@ -328,12 +207,7 @@ int main(int argc, char *argv[])  	QDir::setCurrent(original_path.absolutePath()); -	QGLFormat fmt = QGLFormat::defaultFormat(); -//	fmt.setDirectRendering(false); -//	fmt.setDoubleBuffer(false); - -	csgInfo.glview = new GLView(fmt, NULL);	 -	csgInfo.glview->makeCurrent(); +	csgInfo.glview = new OffscreenView(256, 256);	  	glewInit();  	cout << "GLEW version " << glewGetString(GLEW_VERSION) << "\n"; @@ -352,14 +226,19 @@ int main(int argc, char *argv[])  		cout << "EXT_packed_depth_stencil\n";  	} -//	csgInfo.glview->setRenderFunc(renderGLThrownTogether, &csgInfo); -	csgInfo.glview->setRenderFunc(renderGLviaOpenCSG, &csgInfo);	 -	csgInfo.glview->show(); -	csgInfo.glview->hide(); +	OpenCSGRenderer opencsgRenderer(csgInfo.root_chain, csgInfo.highlights_chain, csgInfo.background_chain, csgInfo.glview->shaderinfo); +//	csgInfo.glview->setRenderFunc(thrownTogetherRenderer); +	csgInfo.glview->setRenderer(&opencsgRenderer); + +	csgInfo.glview->paintGL(); + +	csgInfo.glview->save("out.png"); +	 +// FIXME: Render & Grab buffer -	QImage img = csgInfo.glview->grabFrameBuffer(); -	cout << "Image: " << img.width() << "x" << img.height() << " " << img.format() << "\n"; -	img.save("out.png"); +	// QImage img = csgInfo.glview->grabFrameBuffer(); +	// cout << "Image: " << img.width() << "x" << img.height() << " " << img.format() << "\n"; +	// img.save("out.png");  	destroy_builtin_functions();  	destroy_builtin_modules(); | 
