Browse Source

example for render to png

Former-commit-id: 31a8036e5a67c9cd8689692e93ea1040981b7153
Alec Jacobson (jalec 12 years ago
parent
commit
81c3eb0fdd

+ 2 - 0
.hgignore

@@ -15,4 +15,6 @@ external/yimg/.git*
 external/tinyxml2/CMakeFiles*
 external/tinyxml2/CMakeCache.txt
 external/embree/bin/*
+external/embree/doc/html/*
+external/embree/doc/latex/*
 .DS_Store

+ 3 - 3
examples/bbw/Makefile

@@ -32,15 +32,15 @@ CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 
 
 bbw_demo: obj $(OBJ_FILES)
-	$(CXX) -o bbw_demo $(CFLAGS) $(OBJ_FILES) $(LIB)
+	$(CXX) -o bbw_demo $(CFLAGS) $(AFLAGS) $(OPENMP) $(OBJ_FILES) $(LIB)
 
 obj:
 	mkdir -p obj
 
 obj/%.o: %.cpp %.h
-	$(CXX) $(CFLAGS) -o $@ -c $< $(INC)
+	$(CXX) $(CFLAGS) $(AFLAGS) $(OPENMP) -o $@ -c $< $(INC)
 obj/%.o: %.cpp
-	$(CXX) $(CFLAGS) -o $@ -c $< $(INC)
+	$(CXX) $(CFLAGS) $(AFLAGS) $(OPENMP) -o $@ -c $< $(INC)
 
 .PHONY: clean
 clean:

+ 30 - 0
examples/render_to_png/Makefile

@@ -0,0 +1,30 @@
+
+.PHONY: all
+
+# Shared flags etc.
+include ../../Makefile.conf
+
+# YIMG dependency
+YIMG=../../external/yimg
+YIMG_LIB=-L$(YIMG) -lyimg -lz -L/usr/X11/lib -lpng -bind_at_load
+YIMG_INC=-I/usr/X11/include -I$(YIMG) 
+
+# LIBPNG dependency
+
+all: example
+
+.PHONY: example
+
+IGL=../../
+
+inc=-DIGL_HEADER_ONLY -I$(IGL)/include -I$(DEFAULT_PREFIX)/include $(YIMG_INC)
+lib=-L$(IGL)/lib -ligl -liglpng -L$(DEFAULT_PREFIX)/lib $(OPENGL_LIB) $(GLUT_LIB) $(YIMG_LIB) $(LIBPNG_LIB)
+
+example: example.o
+	g++ $(CFLAGS) -o example example.o $(lib)
+
+example.o: example.cpp
+	g++ $(CFLAGS) -c example.cpp -o example.o $(inc)
+clean:
+	rm -f example.o
+	rm -f example

+ 16 - 0
examples/render_to_png/README

@@ -0,0 +1,16 @@
+Small example to show how to use render_to_png inside a glut application.
+
+Compile with:
+
+make
+
+Run with:
+
+./example
+
+Then hit [space] to take a screen shot. Hit 's' to change the shape.
+
+Produces files in the working directory named:
+render_to_png-example-example-0000.png,
+render_to_png-example-example-0001.png,
+and so on

+ 181 - 0
examples/render_to_png/example.cpp

@@ -0,0 +1,181 @@
+#include <igl/get_seconds.h>
+#include <igl/png/render_to_png.h>
+#include <igl/material_colors.h>
+
+#ifdef __APPLE__
+#   include <GLUT/glut.h>
+#else
+#   include <GL/glut.h>
+#endif
+
+#include <cstdlib>
+#include <cstdio>
+#include <cmath>
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <algorithm>
+
+// This example displays one of the following shapes
+typedef enum { SHAPE_TEAPOT=1, SHAPE_TORUS=2, SHAPE_CONE=3, SHAPE_SPHERE=4 } Shape;
+#define NUM_SHAPES 4
+Shape g_CurrentShape = SHAPE_TEAPOT;
+int width,height;
+double alpha = 0.8;
+int capture_count = 0;
+bool capture_on_next = false;
+
+const float light_pos[4] = {-0.1,-0.1,1.0,0.0};
+
+// Callback function called by GLUT to render screen
+void Display(void)
+{
+  using namespace igl;
+  using namespace std;
+  float v[4]; // will be used to set light paramters
+  
+  // Clear frame buffer
+  glClearColor(1, 1, 1, 0);
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  
+  glEnable(GL_DEPTH_TEST);
+  glDisable(GL_CULL_FACE);
+  glEnable(GL_NORMALIZE);
+  glEnable(GL_LIGHTING);
+  glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
+  
+  // Set light
+  glEnable(GL_LIGHTING);
+  glEnable(GL_LIGHT0);
+  v[0] = v[1] = v[2] = 0.4f; v[3] = 1.0f;
+  glLightfv(GL_LIGHT0, GL_AMBIENT, v);
+  v[0] = v[1] = v[2] = 0.8f; v[3] = 1.0f;
+  glLightfv(GL_LIGHT0, GL_DIFFUSE, v);
+  glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
+  
+  // Set material
+  glDisable(GL_COLOR_MATERIAL);
+  float mat_ambient[4], mat_diffuse[4], mat_specular[4], mat_shininess=128;
+  copy(CYAN_AMBIENT,CYAN_AMBIENT+4,mat_ambient);
+  copy(CYAN_DIFFUSE,CYAN_DIFFUSE+4,mat_diffuse);
+  copy(CYAN_SPECULAR,CYAN_SPECULAR+4,mat_specular);
+  mat_ambient[3] =  alpha;
+  mat_diffuse[3] =  alpha;
+  mat_specular[3] = alpha;
+  glMaterialfv(GL_BACK, GL_AMBIENT,  mat_ambient);
+  glMaterialfv(GL_BACK, GL_DIFFUSE,  mat_diffuse);
+  glMaterialfv(GL_BACK, GL_SPECULAR, mat_specular);
+  glMaterialf( GL_BACK, GL_SHININESS, mat_shininess);
+
+  copy(GOLD_AMBIENT,GOLD_AMBIENT+4,mat_ambient);
+  copy(GOLD_DIFFUSE,GOLD_DIFFUSE+4,mat_diffuse);
+  copy(GOLD_SPECULAR,GOLD_SPECULAR+4,mat_specular);
+  glMaterialfv(GL_FRONT, GL_AMBIENT,  mat_ambient);
+  glMaterialfv(GL_FRONT, GL_DIFFUSE,  mat_diffuse);
+  glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+  glMaterialf( GL_FRONT, GL_SHININESS, mat_shininess);
+  
+  if(g_CurrentShape==SHAPE_TEAPOT)
+  {
+    glFrontFace(GL_CW);
+  }else
+  {
+    glFrontFace(GL_CCW);
+  }
+  // Rotate and draw shape
+  glPushMatrix();
+  glRotated(30,1,0,0);
+  glRotated(360*(fmod(get_seconds(),10.0)/10.0),0,1,0);
+  glScaled(1.5,1.5,1.5);
+  glCallList(g_CurrentShape);
+  glPopMatrix();
+
+  if(capture_on_next)
+  {
+    stringstream padnum; 
+    padnum << "render_to_png-example-" << setw(4) << setfill('0') << capture_count++ << ".png";
+    render_to_png(padnum.str(),width,height);
+    capture_on_next = false;
+  }
+  
+  // Present frame buffer
+  glutSwapBuffers();
+  
+  // Recall Display at next frame
+  glutPostRedisplay();
+}
+
+
+// Callback function called by GLUT when window size changes
+void Reshape(int width, int height)
+{
+  // Set OpenGL viewport and camera
+  glViewport(0, 0, width, height);
+  ::width = width;
+  ::height = height;
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(40, (double)width/height, 1, 10);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  gluLookAt(0,0,5, 0,0,0, 0,1,0);
+  glTranslatef(0, 0.6f, -1);
+}
+
+
+
+void key(unsigned char key, int mouse_x, int mouse_y)
+{
+  using namespace std;
+  switch(key)
+  {
+    case 's':
+      g_CurrentShape = (Shape)((g_CurrentShape)%NUM_SHAPES+1);
+      cout<<"g_CurrentShape: "<<g_CurrentShape<<endl;
+      break;
+    case char(27):
+      exit(0);
+    case ' ':
+      capture_on_next = true;
+      break;
+    default:
+      cout<<"Unknown key command: "<<key<<" "<<int(key)<<endl;
+  }
+}
+
+// Main
+int main(int argc, char *argv[])
+{
+  // Initialize GLUT
+  glutInit(&argc, argv);
+  glutInitDisplayString( "rgba depth double samples>=8 ");
+  glutInitWindowSize(640, 480);
+  glutCreateWindow("render_to_png example (press space to render)");
+  glutCreateMenu(NULL);
+  
+  // Set GLUT callbacks
+  glutDisplayFunc(Display);
+  glutReshapeFunc(Reshape);
+  
+  glutKeyboardFunc(key);
+  
+  // Create some 3D objects (stored in display lists)
+  glNewList(SHAPE_TEAPOT, GL_COMPILE);
+  glutSolidTeapot(1.0);
+  glEndList();
+  glNewList(SHAPE_TORUS, GL_COMPILE);
+  glutSolidTorus(0.3, 1.0, 16, 32);
+  glEndList();
+  glNewList(SHAPE_CONE, GL_COMPILE);
+  glutSolidCone(1.0, 1.5, 64, 4);
+  glEndList();
+  glNewList(SHAPE_SPHERE, GL_COMPILE);
+  glutSolidSphere(1.0, 50, 40);
+  glEndList();
+
+  // Call the GLUT main loop
+  glutMainLoop();
+  
+  return 0;
+}
+

+ 2 - 0
include/igl/REDRUM.h

@@ -11,6 +11,7 @@
 #ifdef IGL_REDRUM_NOOP
 
 // Bold Red, etc.
+#define NORUM(X)     X
 #define REDRUM(X)     X
 #define GREENRUM(X)   X
 #define YELLOWRUM(X)  X
@@ -28,6 +29,7 @@
 #else
 
 // Bold Red, etc.
+#define NORUM(X)       ""<<X<<""
 #define REDRUM(X)      "\e[1m\e[31m"<<X<<"\e[m"
 #define GREENRUM(X)    "\e[1m\e[32m"<<X<<"\e[m"
 #define YELLOWRUM(X)   "\e[1m\e[33m"<<X<<"\e[m"

+ 34 - 5
include/igl/embree/EmbreeIntersector.cpp

@@ -84,6 +84,8 @@ igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3>
   // means more accurate and slower
   //const double eps = DOUBLE_EPS;
   const double eps = FLOAT_EPS;
+  double min_t = embree::zero;
+  bool large_hits_warned = false;
   while(true)
   {
 #ifdef VERBOSE
@@ -93,23 +95,24 @@ igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3>
       endl;
 #endif
     embree::Hit hit;
-    embree::Ray ray(o,d,embree::zero);
+    embree::Ray ray(o,d,min_t);
     num_rays++;
     _intersector->intersect(ray, hit);
     if(hit)
     {
       // Hit self again, progressively advance
-      if(hit.id0 == last_id0)
+      if(hit.id0 == last_id0 || hit.t <= min_t)
       {
         // sanity check
         assert(hit.t<1);
-        // move off origin
+        // push min_t a bit more
         //double t_push = pow(2.0,self_hits-4)*(hit.t<eps?eps:hit.t);
         double t_push = pow(2.0,self_hits)*eps;
 #ifdef VERBOSE
         cout<<"  t_push: "<<t_push<<endl;
 #endif
-        o = o+t_push*d;
+        //o = o+t_push*d;
+        min_t += t_push;
         self_hits++;
       }else
       {
@@ -117,7 +120,10 @@ igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3>
 #ifdef VERBOSE
         cout<<"  t: "<<hit.t<<endl;
 #endif
-        o = o+hit.t*d;
+        // Instead of moving origin, just change min_t. That way calculations
+        // all use exactly same origin values
+        min_t = hit.t;
+
         // reset t_scale
         self_hits = 0;
       }
@@ -127,6 +133,29 @@ igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3>
     {
       break;
     }
+    if(hits.size()>1000 && !large_hits_warned)
+    {
+      cerr<<"Warning: Large number of hits..."<<endl;
+      cerr<<"[ ";
+      for(vector<embree::Hit>::iterator hit = hits.begin();
+          hit != hits.end();
+          hit++)
+      {
+        cerr<<(hit->id0+1)<<" ";
+      }
+      cerr.precision(std::numeric_limits< double >::digits10);
+      cerr<<"[ ";
+      for(vector<embree::Hit>::iterator hit = hits.begin();
+          hit != hits.end();
+          hit++)
+      {
+        cerr<<(hit->t)<<endl;;
+      }
+
+      cerr<<"]"<<endl;
+      large_hits_warned = true;
+      return hits.empty();
+    }
   }
   return hits.empty();
 }