summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/glrender.cc
diff options
context:
space:
mode:
authorDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
committerDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
commitc6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch)
tree1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/utils/asymptote/glrender.cc
parent07ee7222e389b0777456b427a55c22d0e6ffd267 (diff)
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/glrender.cc')
-rw-r--r--Build/source/utils/asymptote/glrender.cc2111
1 files changed, 0 insertions, 2111 deletions
diff --git a/Build/source/utils/asymptote/glrender.cc b/Build/source/utils/asymptote/glrender.cc
deleted file mode 100644
index 822039d934f..00000000000
--- a/Build/source/utils/asymptote/glrender.cc
+++ /dev/null
@@ -1,2111 +0,0 @@
-/*****
- * glrender.cc
- * John Bowman, Orest Shardt, and Supakorn "Jamie" Rassameemasmuang
- * Render 3D Bezier paths and surfaces.
- *****/
-
-#ifdef __CYGWIN__
-#define _POSIX_C_SOURCE 200809L
-#endif
-
-#include <stdlib.h>
-#include <fstream>
-#include <cstring>
-#include <sys/time.h>
-
-#include "common.h"
-#include "locate.h"
-#include "seconds.h"
-#include "statistics.h"
-#include "bezierpatch.h"
-#include "beziercurve.h"
-
-#include "picture.h"
-#include "bbox3.h"
-#include "drawimage.h"
-#include "interact.h"
-#include "fpu.h"
-
-namespace gl {
-#ifdef HAVE_PTHREAD
-pthread_t mainthread;
-#endif
-}
-
-#ifdef HAVE_GL
-#include "tr.h"
-
-#ifdef HAVE_LIBGLUT
-#ifdef __MSDOS__
-#ifndef FGAPI
-#define FGAPI GLUTAPI
-#endif
-#ifndef FGAPIENTRY
-#define FGAPIENTRY APIENTRY
-#endif
-#endif
-
-#define GLUT_BUILDING_LIB
-#endif // HAVE_LIBGLUT
-
-#ifdef HAVE_LIBGLUT
-#ifdef FREEGLUT
-#include <GL/freeglut_ext.h>
-#endif
-#endif
-
-#include "shaders.h"
-
-#ifdef HAVE_LIBOPENIMAGEIO
-#include <OpenImageIO/imageio.h>
-#endif
-
-using settings::locateFile;
-using utils::seconds;
-
-namespace camp {
-Billboard BB;
-
-GLint pixelShader;
-GLint materialShader;
-GLint colorShader;
-GLint transparentShader;
-
-vertexBuffer material0Data(GL_POINTS);
-vertexBuffer material1Data(GL_LINES);
-vertexBuffer materialData;
-vertexBuffer colorData;
-vertexBuffer transparentData;
-vertexBuffer triangleData;
-
-const size_t Nbuffer=10000;
-const size_t nbuffer=1000;
-}
-
-#endif /* HAVE_GL */
-
-#ifdef HAVE_LIBGLM
-using camp::Material;
-using camp::Maxmaterials;
-using camp::Nmaterials;
-using camp::nmaterials;
-using camp::MaterialMap;
-
-namespace camp {
-std::vector<Material> material;
-MaterialMap materialMap;
-size_t materialIndex;
-
-size_t Maxmaterials;
-size_t Nmaterials=1;
-size_t nmaterials=48;
-}
-
-extern void exitHandler(int);
-
-namespace gl {
-
-bool outlinemode=false;
-bool glthread=false;
-bool glupdate=false;
-bool glexit=false;
-bool initialize=true;
-
-using camp::picture;
-using camp::drawRawImage;
-using camp::transform;
-using camp::pair;
-using camp::triple;
-using vm::array;
-using vm::read;
-using camp::bbox3;
-using settings::getSetting;
-using settings::Setting;
-
-bool Iconify=false;
-bool ignorezoom;
-int Fitscreen=1;
-bool firstFit;
-
-bool queueExport=false;
-bool readyAfterExport=false;
-bool remesh;
-
-int Mode;
-
-double Aspect;
-bool View;
-int Oldpid;
-string Prefix;
-const picture* Picture;
-string Format;
-int fullWidth,fullHeight;
-int Width,Height;
-double oWidth,oHeight;
-int screenWidth,screenHeight;
-int maxTileWidth;
-int maxTileHeight;
-
-double Angle;
-bool orthographic;
-double H;
-double xmin,xmax;
-double ymin,ymax;
-double zmin,zmax;
-
-double Xmin,Xmax;
-double Ymin,Ymax;
-
-pair Shift;
-pair Margin;
-double X,Y;
-int x0,y0;
-double cx,cy;
-double Xfactor,Yfactor;
-double ArcballFactor;
-
-static const double pi=acos(-1.0);
-static const double degrees=180.0/pi;
-static const double radians=1.0/degrees;
-
-double *Background;
-size_t Nlights=1; // Maximum number of lights compiled in shader
-size_t nlights; // Actual number of lights
-size_t nlights0;
-triple *Lights;
-double *Diffuse;
-double *Specular;
-bool antialias;
-
-double Zoom;
-double Zoom0;
-double lastzoom;
-
-GLint lastshader=-1;
-
-using glm::dvec3;
-using glm::dmat3;
-using glm::mat3;
-using glm::mat4;
-using glm::dmat4;
-using glm::value_ptr;
-using glm::translate;
-
-mat3 normMat;
-dmat3 dnormMat;
-
-mat4 projViewMat;
-mat4 viewMat;
-
-dmat4 dprojMat;
-dmat4 dprojViewMat;
-dmat4 dviewMat;
-dmat4 drotateMat;
-
-const double *dprojView;
-const double *dView;
-double BBT[9];
-
-unsigned int framecount;
-
-template<class T>
-inline T min(T a, T b)
-{
- return (a < b) ? a : b;
-}
-
-template<class T>
-inline T max(T a, T b)
-{
- return (a > b) ? a : b;
-}
-
-glm::vec4 vec4(triple v)
-{
- return glm::vec4(v.getx(),v.gety(),v.getz(),0);
-}
-
-glm::vec4 vec4(double *v)
-{
- return glm::vec4(v[0],v[1],v[2],v[3]);
-}
-
-void setDimensions(int Width, int Height, double X, double Y)
-{
- double Aspect=((double) Width)/Height;
- double xshift=(X/Width+Shift.getx()*Xfactor)*Zoom;
- double yshift=(Y/Height+Shift.gety()*Yfactor)*Zoom;
- double Zoominv=1.0/lastzoom;
- if(orthographic) {
- double xsize=Xmax-Xmin;
- double ysize=Ymax-Ymin;
- if(xsize < ysize*Aspect) {
- double r=0.5*ysize*Aspect*Zoominv;
- double X0=2.0*r*xshift;
- double Y0=(Ymax-Ymin)*Zoominv*yshift;
- xmin=-r-X0;
- xmax=r-X0;
- ymin=Ymin*Zoominv-Y0;
- ymax=Ymax*Zoominv-Y0;
- } else {
- double r=0.5*xsize/(Aspect*Zoom);
- double X0=(Xmax-Xmin)*Zoominv*xshift;
- double Y0=2.0*r*yshift;
- xmin=Xmin*Zoominv-X0;
- xmax=Xmax*Zoominv-X0;
- ymin=-r-Y0;
- ymax=r-Y0;
- }
- } else {
- double r=H*Zoominv;
- double rAspect=r*Aspect;
- double X0=2.0*rAspect*xshift;
- double Y0=2.0*r*yshift;
- xmin=-rAspect-X0;
- xmax=rAspect-X0;
- ymin=-r-Y0;
- ymax=r-Y0;
- }
-}
-
-void updateProjection()
-{
- dprojViewMat=dprojMat*dviewMat;
- projViewMat=mat4(dprojViewMat);
- dprojView=value_ptr(dprojViewMat);
-}
-
-void frustum(GLdouble left, GLdouble right, GLdouble bottom,
- GLdouble top, GLdouble nearVal, GLdouble farVal)
-{
- dprojMat=glm::frustum(left,right,bottom,top,nearVal,farVal);
- updateProjection();
-}
-
-void ortho(GLdouble left, GLdouble right, GLdouble bottom,
- GLdouble top, GLdouble nearVal, GLdouble farVal)
-{
- dprojMat=glm::ortho(left,right,bottom,top,nearVal,farVal);
- updateProjection();
-}
-
-void setProjection()
-{
- setDimensions(Width,Height,X,Y);
- if(orthographic) ortho(xmin,xmax,ymin,ymax,-zmax,-zmin);
- else frustum(xmin,xmax,ymin,ymax,-zmax,-zmin);
-}
-
-void updateModelViewData()
-{
- // Like Fortran, OpenGL uses transposed (column-major) format!
- dnormMat=dmat3(glm::inverse(dviewMat));
- double *T=value_ptr(dnormMat);
- for(size_t i=0; i < 9; ++i)
- BBT[i]=T[i];
- normMat=mat3(dnormMat);
-}
-
-bool Xspin,Yspin,Zspin;
-bool Animate;
-bool Step;
-
-#ifdef HAVE_GL
-
-void idle()
-{
- glutIdleFunc(NULL);
- Xspin=Yspin=Zspin=Animate=Step=false;
-}
-#endif
-
-void home(bool webgl=false)
-{
- X=Y=cx=cy=0.0;
-#ifdef HAVE_GL
-#ifdef HAVE_LIBGLUT
-#ifndef HAVE_LIBOSMESA
- if(!webgl)
- idle();
-#endif
-#endif
-#endif
- dviewMat=dmat4(1.0);
- dView=value_ptr(dviewMat);
- viewMat=mat4(dviewMat);
-
- drotateMat=dmat4(1.0);
-
- updateModelViewData();
-
- remesh=true;
- lastzoom=Zoom=Zoom0;
- setDimensions(Width,Height,0,0);
- framecount=0;
-}
-
-#ifdef HAVE_GL
-
-double T[16];
-
-#ifdef HAVE_LIBGLUT
-timeval lasttime;
-timeval lastframetime;
-int oldWidth,oldHeight;
-
-bool queueScreen=false;
-
-string Action;
-
-double lastangle;
-int window;
-#endif
-
-using utils::statistics;
-statistics S;
-
-#ifdef HAVE_LIBOPENIMAGEIO
-GLuint envMapBuf;
-
-GLuint initHDR() {
- GLuint tex;
- glGenTextures(1, &tex);
-
- auto imagein = OIIO::ImageInput::open(locateFile("res/studio006.hdr").c_str());
- OIIO::ImageSpec const& imspec = imagein->spec();
-
- // uses GL_TEXTURE1 for now.
- glActiveTexture(GL_TEXTURE1);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glBindTexture(GL_TEXTURE_2D, tex);
- std::vector<float> pixels(imspec.width*imspec.height*3);
- imagein->read_image(pixels.data());
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imspec.width, imspec.height, 0,
- GL_RGB, GL_FLOAT, pixels.data());
-
- glGenerateMipmap(GL_TEXTURE_2D);
- imagein->close();
-
- glActiveTexture(GL_TEXTURE0);
- return tex;
-}
-
-#endif
-GLint shaderProg,shaderProgColor;
-
-void *glrenderWrapper(void *a);
-
-#ifdef HAVE_LIBOSMESA
-OSMesaContext ctx;
-unsigned char *osmesa_buffer;
-#endif
-
-#ifdef HAVE_PTHREAD
-
-pthread_cond_t initSignal=PTHREAD_COND_INITIALIZER;
-pthread_mutex_t initLock=PTHREAD_MUTEX_INITIALIZER;
-
-pthread_cond_t readySignal=PTHREAD_COND_INITIALIZER;
-pthread_mutex_t readyLock=PTHREAD_MUTEX_INITIALIZER;
-
-void endwait(pthread_cond_t& signal, pthread_mutex_t& lock)
-{
- pthread_mutex_lock(&lock);
- pthread_cond_signal(&signal);
- pthread_mutex_unlock(&lock);
-}
-void wait(pthread_cond_t& signal, pthread_mutex_t& lock)
-{
- pthread_mutex_lock(&lock);
- pthread_cond_signal(&signal);
- pthread_cond_wait(&signal,&lock);
- pthread_mutex_unlock(&lock);
-}
-#endif
-
-void initShaders()
-{
- Nlights=nlights == 0 ? 0 : max(Nlights,nlights);
- Nmaterials=max(Nmaterials,nmaterials);
-
- shaderProg=glCreateProgram();
- string vs=locateFile("shaders/vertex.glsl");
- string fs=locateFile("shaders/fragment.glsl");
- if(vs.empty() || fs.empty()) {
- cerr << "GLSL shaders not found." << endl;
- exit(-1);
- }
-
- std::vector<std::string> shaderParams;
-
-#if HAVE_LIBOPENIMAGEIO
- if (getSetting<bool>("envmap")) {
- shaderParams.push_back("ENABLE_TEXTURE");
- envMapBuf=initHDR();
- }
-#endif
-
- std::vector<ShaderfileModePair> shaders;
- shaders.push_back(ShaderfileModePair(vs.c_str(),GL_VERTEX_SHADER));
- shaders.push_back(ShaderfileModePair(fs.c_str(),GL_FRAGMENT_SHADER));
- if(orthographic)
- shaderParams.push_back("ORTHOGRAPHIC");
-
- shaderParams.push_back("WIDTH");
- camp::pixelShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
- shaderParams);
- shaderParams.pop_back();
-
- shaderParams.push_back("NORMAL");
- camp::materialShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
- shaderParams);
- shaderParams.push_back("COLOR");
- camp::colorShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
- shaderParams);
- shaderParams.push_back("TRANSPARENT");
- camp::transparentShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
- shaderParams);
-}
-
-void deleteShaders()
-{
- glDeleteProgram(camp::transparentShader);
- glDeleteProgram(camp::colorShader);
- glDeleteProgram(camp::materialShader);
- glDeleteProgram(camp::pixelShader);
-}
-
-void setBuffers()
-{
- GLuint vao;
- glGenVertexArrays(1,&vao);
- glBindVertexArray(vao);
-
- camp::material0Data.reserve0();
- camp::materialData.reserve();
- camp::colorData.Reserve();
- camp::triangleData.Reserve();
- camp::transparentData.Reserve();
-}
-
-void drawscene(int Width, int Height)
-{
-#ifdef HAVE_PTHREAD
- static bool first=true;
- if(glthread && first) {
- wait(initSignal,initLock);
- endwait(initSignal,initLock);
- first=false;
- }
-#endif
-
- if((nlights == 0 && Nlights > 0) || nlights > Nlights ||
- nmaterials > Nmaterials) {
- deleteShaders();
- initShaders();
- lastshader=-1;
- }
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- triple m(xmin,ymin,zmin);
- triple M(xmax,ymax,zmax);
- double perspective=orthographic ? 0.0 : 1.0/zmax;
-
- double size2=hypot(Width,Height);
-
- if(remesh)
- camp::drawElement::center.clear();
-
- Picture->render(size2,m,M,perspective,remesh);
-
- if(!outlinemode) remesh=false;
-}
-
-// Return x divided by y rounded up to the nearest integer.
-int Quotient(int x, int y)
-{
- return (x+y-1)/y;
-}
-
-void Export()
-{
- glReadBuffer(GL_BACK_LEFT);
- glPixelStorei(GL_PACK_ALIGNMENT,1);
- glFinish();
- try {
- size_t ndata=3*fullWidth*fullHeight;
- unsigned char *data=new unsigned char[ndata];
- if(data) {
- TRcontext *tr=trNew();
- int width=Quotient(fullWidth,Quotient(fullWidth,min(maxTileWidth,Width)));
- int height=Quotient(fullHeight,Quotient(fullHeight,
- min(maxTileHeight,Height)));
- if(settings::verbose > 1)
- cout << "Exporting " << Prefix << " as " << fullWidth << "x"
- << fullHeight << " image" << " using tiles of size "
- << width << "x" << height << endl;
-
- unsigned border=min(min(1,width/2),height/2);
- trTileSize(tr,width,height,border);
- trImageSize(tr,fullWidth,fullHeight);
- trImageBuffer(tr,GL_RGB,GL_UNSIGNED_BYTE,data);
-
- setDimensions(fullWidth,fullHeight,X/Width*fullWidth,Y/Width*fullWidth);
- (orthographic ? trOrtho : trFrustum)(tr,xmin,xmax,ymin,ymax,-zmax,-zmin);
-
- size_t count=0;
- do {
- trBeginTile(tr);
- remesh=true;
- drawscene(fullWidth,fullHeight);
- ++count;
- } while (trEndTile(tr));
- if(settings::verbose > 1)
- cout << count << " tile" << (count != 1 ? "s" : "") << " drawn" << endl;
- trDelete(tr);
-
- picture pic;
- double w=oWidth;
- double h=oHeight;
- double Aspect=((double) fullWidth)/fullHeight;
- if(w > h*Aspect) w=(int) (h*Aspect+0.5);
- else h=(int) (w/Aspect+0.5);
- // Render an antialiased image.
- drawRawImage *Image=new drawRawImage(data,fullWidth,fullHeight,
- transform(0.0,0.0,w,0.0,0.0,h),
- antialias);
- pic.append(Image);
- pic.shipout(NULL,Prefix,Format,false,View);
- delete Image;
- delete[] data;
- }
- } catch(handled_error) {
- } catch(std::bad_alloc&) {
- outOfMemory();
- }
- remesh=true;
- setProjection();
-
-#ifndef HAVE_LIBOSMESA
-#ifdef HAVE_LIBGLUT
- glutPostRedisplay();
-#endif
-
-#ifdef HAVE_PTHREAD
- if(glthread && readyAfterExport) {
- readyAfterExport=false;
- endwait(readySignal,readyLock);
- }
-#endif
-#endif
-}
-
-void nodisplay()
-{
-}
-
-void destroywindow()
-{
- glutDestroyWindow(glutGetWindow());
-}
-
-// Return the greatest power of 2 less than or equal to n.
-inline unsigned int floorpow2(unsigned int n)
-{
- n |= n >> 1;
- n |= n >> 2;
- n |= n >> 4;
- n |= n >> 8;
- n |= n >> 16;
- return n-(n >> 1);
-}
-
-void quit()
-{
-#ifdef HAVE_LIBOSMESA
- if(osmesa_buffer) delete[] osmesa_buffer;
- if(ctx) OSMesaDestroyContext(ctx);
- exit(0);
-#endif
-#ifdef HAVE_LIBGLUT
- if(glthread) {
- bool animating=getSetting<bool>("animating");
- if(animating)
- Setting("interrupt")=true;
- home();
- Animate=getSetting<bool>("autoplay");
-#ifdef HAVE_PTHREAD
- if(!interact::interactive || animating) {
- idle();
- glutDisplayFunc(nodisplay);
- endwait(readySignal,readyLock);
- }
-#endif
- if(interact::interactive)
- glutHideWindow();
- } else {
- glutDestroyWindow(window);
- exit(0);
- }
-#endif
-}
-
-void mode()
-{
- remesh=true;
- switch(Mode) {
- case 0: // regular
- outlinemode=false;
- nlights=nlights0;
- lastshader=-1;
- glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
- ++Mode;
- break;
- case 1: // outline
- outlinemode=true;
- nlights=0;
- glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
- ++Mode;
- break;
- case 2: // wireframe
- outlinemode=false;
- Mode=0;
- break;
- }
-#ifdef HAVE_LIBGLUT
-#ifndef HAVE_LIBOSMESA
- glutPostRedisplay();
-#endif
-#endif
-}
-
-// GUI-related functions
-#ifdef HAVE_LIBGLUT
-bool capsize(int& width, int& height)
-{
- bool resize=false;
- if(width > screenWidth) {
- width=screenWidth;
- resize=true;
- }
- if(height > screenHeight) {
- height=screenHeight;
- resize=true;
- }
- return resize;
-}
-
-void reshape0(int width, int height)
-{
- X=(X/Width)*width;
- Y=(Y/Height)*height;
-
- Width=width;
- Height=height;
-
- setProjection();
- glViewport(0,0,Width,Height);
-}
-
-void windowposition(int& x, int& y, int width=Width, int height=Height)
-{
- pair z=getSetting<pair>("position");
- x=(int) z.getx();
- y=(int) z.gety();
- if(x < 0) {
- x += screenWidth-width;
- if(x < 0) x=0;
- }
- if(y < 0) {
- y += screenHeight-height;
- if(y < 0) y=0;
- }
-}
-
-void setsize(int w, int h, bool reposition=true)
-{
- int x,y;
-
- capsize(w,h);
- if(reposition) {
- windowposition(x,y,w,h);
- glutPositionWindow(x,y);
- } else
- glutPositionWindow(max(glutGet(GLUT_WINDOW_X)-2,0),
- max(glutGet(GLUT_WINDOW_Y)-2,0));
-
- glutReshapeWindow(w,h);
- reshape0(w,h);
- glutPostRedisplay();
-}
-
-void capzoom()
-{
- static double maxzoom=sqrt(DBL_MAX);
- static double minzoom=1.0/maxzoom;
- if(Zoom <= minzoom) Zoom=minzoom;
- if(Zoom >= maxzoom) Zoom=maxzoom;
-
- if(Zoom != lastzoom) remesh=true;
- lastzoom=Zoom;
-}
-
-void fullscreen(bool reposition=true)
-{
- Width=screenWidth;
- Height=screenHeight;
- if(firstFit) {
- if(Width < Height*Aspect)
- Zoom *= Width/(Height*Aspect);
- capzoom();
- setProjection();
- firstFit=false;
- }
- Xfactor=((double) screenHeight)/Height;
- Yfactor=((double) screenWidth)/Width;
- reshape0(Width,Height);
- if(reposition)
- glutPositionWindow(0,0);
- glutReshapeWindow(Width,Height);
- glutPostRedisplay();
-}
-
-void fitscreen(bool reposition=true)
-{
- if(Animate && Fitscreen == 2) Fitscreen=0;
- switch(Fitscreen) {
- case 0: // Original size
- {
- Xfactor=Yfactor=1.0;
- double pixelRatio=getSetting<double>("devicepixelratio");
- setsize(oldWidth*pixelRatio,oldHeight*pixelRatio,reposition);
- break;
- }
- case 1: // Fit to screen in one dimension
- {
- oldWidth=Width;
- oldHeight=Height;
- int w=screenWidth;
- int h=screenHeight;
- if(w > h*Aspect)
- w=min((int) ceil(h*Aspect),w);
- else
- h=min((int) ceil(w/Aspect),h);
- setsize(w,h,reposition);
- break;
- }
- case 2: // Full screen
- {
- fullscreen(reposition);
- break;
- }
- }
-}
-
-void togglefitscreen()
-{
- ++Fitscreen;
- if(Fitscreen > 2) Fitscreen=0;
- fitscreen();
-}
-
-void initTimer()
-{
- gettimeofday(&lasttime,NULL);
- gettimeofday(&lastframetime,NULL);
-}
-
-void idleFunc(void (*f)())
-{
- initTimer();
- glutIdleFunc(f);
-}
-
-void screen()
-{
- if(glthread && !interact::interactive)
- fitscreen(false);
-}
-
-void nextframe(int)
-{
-#ifdef HAVE_PTHREAD
- endwait(readySignal,readyLock);
-#endif
- double framedelay=getSetting<double>("framedelay");
- if(framedelay > 0)
- usleep((unsigned int) (1000.0*framedelay+0.5));
- if(Step) Animate=false;
-}
-
-void display()
-{
- if(queueScreen) {
- if(!Animate) screen();
- queueScreen=false;
- }
-
- bool fps=settings::verbose > 2;
- drawscene(Width,Height);
- if(fps) {
- if(framecount < 10) // Measure steady-state framerate
- seconds();
- else {
- double s=seconds();
- if(s > 0.0) {
- double rate=1.0/s;
- S.add(rate);
- cout << "FPS=" << rate << "\t" << S.mean() << " +/- " << S.stdev()
- << endl;
- }
- }
- ++framecount;
- }
- glutSwapBuffers();
-
-#ifdef HAVE_PTHREAD
- if(glthread && Animate) {
- queueExport=false;
- double delay=1.0/getSetting<double>("framerate");
- timeval tv;
- gettimeofday(&tv,NULL);
- double seconds=tv.tv_sec-lastframetime.tv_sec+
- ((double) tv.tv_usec-lastframetime.tv_usec)/1000000.0;
- lastframetime=tv;
- double milliseconds=1000.0*(delay-seconds);
- double framedelay=getSetting<double>("framedelay");
- if(framedelay > 0) milliseconds -= framedelay;
- if(milliseconds > 0)
- glutTimerFunc((int) (milliseconds+0.5),nextframe,0);
- else nextframe(0);
- }
-#endif
- if(queueExport) {
- Export();
- queueExport=false;
- }
- if(!glthread) {
- if(Oldpid != 0 && waitpid(Oldpid,NULL,WNOHANG) != Oldpid) {
- kill(Oldpid,SIGHUP);
- Oldpid=0;
- }
- }
-}
-
-void update()
-{
- glutDisplayFunc(display);
- Animate=getSetting<bool>("autoplay");
- glutShowWindow();
- if(Zoom != lastzoom) remesh=true;
-
- lastzoom=Zoom;
- double cz=0.5*(zmin+zmax);
-
- dviewMat=translate(translate(dmat4(1.0),dvec3(cx,cy,cz))*drotateMat,
- dvec3(0,0,-cz));
- dView=value_ptr(dviewMat);
- viewMat=mat4(dviewMat);
-
- setProjection();
- updateModelViewData();
-
- glutPostRedisplay();
-}
-
-void updateHandler(int)
-{
- queueScreen=true;
- remesh=true;
- update();
- if(interact::interactive || !Animate) {
- glutShowWindow();
- }
-}
-
-void poll(int)
-{
- if(glupdate) {
- updateHandler(0);
- glupdate=false;
- }
- if(glexit) {
- exitHandler(0);
- glexit=false;
- }
- glutTimerFunc(100.0,poll,0);
-}
-
-void animate()
-{
- Animate=!Animate;
- if(Animate) {
- if(Fitscreen == 2) {
- togglefitscreen();
- togglefitscreen();
- }
- update();
- } else idle();
-}
-
-void reshape(int width, int height)
-{
- if(glthread) {
- static bool initialize=true;
- if(initialize) {
- initialize=false;
- Signal(SIGUSR1,updateHandler);
- }
- }
-
- if(capsize(width,height))
- glutReshapeWindow(width,height);
-
- reshape0(width,height);
- remesh=true;
-}
-
-void shift(int x, int y)
-{
- double Zoominv=1.0/Zoom;
- X += (x-x0)*Zoominv;
- Y += (y0-y)*Zoominv;
- x0=x; y0=y;
- update();
-}
-
-void pan(int x, int y)
-{
- if(orthographic) {
- double Zoominv=1.0/Zoom;
- X += (x-x0)*Zoominv;
- Y += (y0-y)*Zoominv;
- } else {
- cx += (x-x0)*(xmax-xmin)/Width;
- cy += (y0-y)*(ymax-ymin)/Height;
- }
- x0=x; y0=y;
- update();
-}
-
-void zoom(int x, int y)
-{
- if(ignorezoom) {ignorezoom=false; y0=y; return;}
- double zoomFactor=getSetting<double>("zoomfactor");
- if(zoomFactor > 0.0) {
- double zoomStep=getSetting<double>("zoomstep");
- const double limit=log(0.1*DBL_MAX)/log(zoomFactor);
- double stepPower=zoomStep*(y0-y);
- if(fabs(stepPower) < limit) {
- Zoom *= pow(zoomFactor,stepPower);
- capzoom();
- y0=y;
- setProjection();
- glutPostRedisplay();
- }
- }
-}
-
-void mousewheel(int wheel, int direction, int x, int y)
-{
- double zoomFactor=getSetting<double>("zoomfactor");
- if(zoomFactor > 0.0) {
- if(direction > 0)
- Zoom *= zoomFactor;
- else
- Zoom /= zoomFactor;
- capzoom();
- setProjection();
- glutPostRedisplay();
- }
-}
-
-struct arcball {
- double angle;
- triple axis;
-
- arcball(double x0, double y0, double x, double y) {
- triple v0=norm(x0,y0);
- triple v1=norm(x,y);
- double Dot=dot(v0,v1);
- angle=Dot > 1.0 ? 0.0 : Dot < -1.0 ? pi : acos(Dot);
- axis=unit(cross(v0,v1));
- }
-
- triple norm(double x, double y) {
- double norm=hypot(x,y);
- if(norm > 1.0) {
- double denom=1.0/norm;
- x *= denom;
- y *= denom;
- }
- return triple(x,y,sqrt(max(1.0-x*x-y*y,0.0)));
- }
-};
-
-inline double glx(int x) {
- return 2.0*x/Width-1.0;
-}
-
-inline double gly(int y) {
- return 1.0-2.0*y/Height;
-}
-
-void rotate(int x, int y)
-{
- if(x != x0 || y != y0) {
- arcball A(glx(x0),gly(y0),glx(x),gly(y));
- triple v=A.axis;
- drotateMat=glm::rotate<double>(2*A.angle/lastzoom*ArcballFactor,
- glm::dvec3(v.getx(),v.gety(),v.getz()))*
- drotateMat;
- x0=x; y0=y;
- update();
- }
-}
-
-double Degrees(int x, int y)
-{
- return atan2(0.5*Height-y-Y,x-0.5*Width-X)*degrees;
-}
-
-void rotateX(double step)
-{
- dmat4 tmpRot(1.0);
- tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(1,0,0));
- drotateMat=tmpRot*drotateMat;
- update();
-}
-
-void rotateY(double step)
-{
- dmat4 tmpRot(1.0);
- tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(0,1,0));
- drotateMat=tmpRot*drotateMat;
- update();
-}
-
-void rotateZ(double step)
-{
- dmat4 tmpRot(1.0);
- tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(0,0,1));
- drotateMat=tmpRot*drotateMat;
- update();
-}
-
-void rotateX(int x, int y)
-{
- double angle=Degrees(x,y);
- rotateX(angle-lastangle);
- lastangle=angle;
-}
-
-void rotateY(int x, int y)
-{
- double angle=Degrees(x,y);
- rotateY(angle-lastangle);
- lastangle=angle;
-}
-
-void rotateZ(int x, int y)
-{
- double angle=Degrees(x,y);
- rotateZ(angle-lastangle);
- lastangle=angle;
-}
-
-#ifndef GLUT_WHEEL_UP
-#define GLUT_WHEEL_UP 3
-#endif
-
-#ifndef GLUT_WHEEL_DOWN
-#define GLUT_WHEEL_DOWN 4
-#endif
-
-string action(int button, int mod)
-{
- size_t Button;
- size_t nButtons=5;
- switch(button) {
- case GLUT_LEFT_BUTTON:
- Button=0;
- break;
- case GLUT_MIDDLE_BUTTON:
- Button=1;
- break;
- case GLUT_RIGHT_BUTTON:
- Button=2;
- break;
- case GLUT_WHEEL_UP:
- Button=3;
- break;
- case GLUT_WHEEL_DOWN:
- Button=4;
- break;
- default:
- Button=nButtons;
- }
-
- size_t Mod;
- size_t nMods=4;
- switch(mod) {
- case 0:
- Mod=0;
- break;
- case GLUT_ACTIVE_SHIFT:
- Mod=1;
- break;
- case GLUT_ACTIVE_CTRL:
- Mod=2;
- break;
- case GLUT_ACTIVE_ALT:
- Mod=3;
- break;
- default:
- Mod=nMods;
- }
-
- if(Button < nButtons) {
- array *left=getSetting<array *>("leftbutton");
- array *middle=getSetting<array *>("middlebutton");
- array *right=getSetting<array *>("rightbutton");
- array *wheelup=getSetting<array *>("wheelup");
- array *wheeldown=getSetting<array *>("wheeldown");
- array *Buttons[]={left,middle,right,wheelup,wheeldown};
- array *a=Buttons[button];
- size_t size=checkArray(a);
- if(Mod < size)
- return read<string>(a,Mod);
- }
- return "";
-}
-
-void timeout(int)
-{
-}
-
-void mouse(int button, int state, int x, int y)
-{
- int mod=glutGetModifiers();
- string Action=action(button,mod);
-
- if(Action == "zoomin") {
- glutMotionFunc(NULL);
- mousewheel(0,1,x,y);
- return;
- }
- if(Action == "zoomout") {
- glutMotionFunc(NULL);
- mousewheel(0,-1,x,y);
- return;
- }
-
- if(state == GLUT_DOWN) {
- if(Action == "rotate") {
- x0=x; y0=y;
- glutMotionFunc(rotate);
- } else if(Action == "shift") {
- x0=x; y0=y;
- glutMotionFunc(shift);
- } else if(Action == "pan") {
- x0=x; y0=y;
- glutMotionFunc(pan);
- } else if(Action == "zoom" || Action == "zoom/menu") {
- y0=y;
- glutMotionFunc(zoom);
- } else if(Action == "rotateX") {
- lastangle=Degrees(x,y);
- glutMotionFunc(rotateX);
- } else if(Action == "rotateY") {
- lastangle=Degrees(x,y);
- glutMotionFunc(rotateY);
- } else if(Action == "rotateZ") {
- lastangle=Degrees(x,y);
- glutMotionFunc(rotateZ);
- }
- } else {
- glutMotionFunc(NULL);
- }
-}
-
-double spinstep()
-{
- timeval tv;
- gettimeofday(&tv,NULL);
- double step=getSetting<double>("spinstep")*
- (tv.tv_sec-lasttime.tv_sec+
- ((double) tv.tv_usec-lasttime.tv_usec)/1000000.0);
- lasttime=tv;
- return step;
-}
-
-void xspin()
-{
- rotateX(spinstep());
-}
-
-void yspin()
-{
- rotateY(spinstep());
-}
-
-void zspin()
-{
- rotateZ(spinstep());
-}
-
-void expand()
-{
- double resizeStep=getSetting<double>("resizestep");
- if(resizeStep > 0.0)
- setsize((int) (Width*resizeStep+0.5),(int) (Height*resizeStep+0.5));
-}
-
-void shrink()
-{
- double resizeStep=getSetting<double>("resizestep");
- if(resizeStep > 0.0)
- setsize(max((int) (Width/resizeStep+0.5),1),
- max((int) (Height/resizeStep+0.5),1));
-}
-
-void spinx()
-{
- if(Xspin)
- idle();
- else {
- idleFunc(xspin);
- Xspin=true;
- Yspin=Zspin=false;
- }
-}
-
-void spiny()
-{
- if(Yspin)
- idle();
- else {
- idleFunc(yspin);
- Yspin=true;
- Xspin=Zspin=false;
- }
-}
-
-void spinz()
-{
- if(Zspin)
- idle();
- else {
- idleFunc(zspin);
- Zspin=true;
- Xspin=Yspin=false;
- }
-}
-
-void showCamera()
-{
- projection P=camera();
- string projection=P.orthographic ? "orthographic(" : "perspective(";
- string indent(2+projection.length(),' ');
- cout << endl
- << "currentprojection=" << endl << " "
- << projection << "camera=" << P.camera << "," << endl
- << indent << "up=" << P.up << "," << endl
- << indent << "target=" << P.target << "," << endl
- << indent << "zoom=" << P.zoom;
- if(!orthographic)
- cout << "," << endl << indent << "angle=" << P.angle;
- if(P.viewportshift != pair(0.0,0.0))
- cout << "," << endl << indent << "viewportshift=" << P.viewportshift*Zoom;
- if(!orthographic)
- cout << "," << endl << indent << "autoadjust=false";
- cout << ");" << endl;
-}
-
-void keyboard(unsigned char key, int x, int y)
-{
- switch(key) {
- case 'h':
- home();
- update();
- break;
- case 'f':
- togglefitscreen();
- break;
- case 'x':
- spinx();
- break;
- case 'y':
- spiny();
- break;
- case 'z':
- spinz();
- break;
- case 's':
- idle();
- break;
- case 'm':
- mode();
- break;
- case 'e':
- Export();
- break;
- case 'c':
- showCamera();
- break;
- case '+':
- case '=':
- case '>':
- expand();
- break;
- case '-':
- case '_':
- case '<':
- shrink();
- break;
- case 'p':
- if(getSetting<bool>("reverse")) Animate=false;
- Setting("reverse")=Step=false;
- animate();
- break;
- case 'r':
- if(!getSetting<bool>("reverse")) Animate=false;
- Setting("reverse")=true;
- Step=false;
- animate();
- break;
- case ' ':
- Step=true;
- animate();
- break;
- case 17: // Ctrl-q
- case 'q':
- if(!Format.empty()) Export();
- quit();
- break;
- }
-}
-
-void setosize()
-{
- oldWidth=(int) ceil(oWidth);
- oldHeight=(int) ceil(oHeight);
-}
-#endif
-// end of GUI-related functions
-
-void exportHandler(int=0)
-{
-#ifdef HAVE_LIBGLUT
-#ifndef HAVE_LIBOSMESA
- if(!Iconify)
- glutShowWindow();
-#endif
-#endif
- readyAfterExport=true;
- Export();
-
-#ifdef HAVE_LIBGLUT
-#ifndef HAVE_LIBOSMESA
- if(!Iconify)
- glutHideWindow();
- glutDisplayFunc(nodisplay);
-#endif
-#endif
-}
-
-static bool glinitialize=true;
-
-projection camera(bool user)
-{
- if(glinitialize) return projection();
-
- camp::Triple vCamera,vUp,vTarget;
-
- double cz=0.5*(zmin+zmax);
-
- double *Rotate=value_ptr(drotateMat);
-
- if(user) {
- for(int i=0; i < 3; ++i) {
- double sumCamera=0.0, sumTarget=0.0, sumUp=0.0;
- int i4=4*i;
- for(int j=0; j < 4; ++j) {
- int j4=4*j;
- double R0=Rotate[j4];
- double R1=Rotate[j4+1];
- double R2=Rotate[j4+2];
- double R3=Rotate[j4+3];
- double T4ij=T[i4+j];
- sumCamera += T4ij*(R3-cx*R0-cy*R1-cz*R2);
- sumUp += T4ij*R1;
- sumTarget += T4ij*(R3-cx*R0-cy*R1);
- }
- vCamera[i]=sumCamera;
- vUp[i]=sumUp;
- vTarget[i]=sumTarget;
- }
- } else {
- for(int i=0; i < 3; ++i) {
- int i4=4*i;
- double R0=Rotate[i4];
- double R1=Rotate[i4+1];
- double R2=Rotate[i4+2];
- double R3=Rotate[i4+3];
- vCamera[i]=R3-cx*R0-cy*R1-cz*R2;
- vUp[i]=R1;
- vTarget[i]=R3-cx*R0-cy*R1;
- }
- }
-
- return projection(orthographic,vCamera,vUp,vTarget,Zoom,
- 2.0*atan(tan(0.5*Angle)/Zoom)/radians,
- pair(X/Width+Shift.getx(),
- Y/Height+Shift.gety()));
-}
-
-void init()
-{
-#ifdef HAVE_LIBGLUT
- mem::vector<string> cmd;
- cmd.push_back(settings::argv0);
- if(!interact::interactive && Iconify)
- cmd.push_back("-iconic");
- push_split(cmd,getSetting<string>("glOptions"));
- char **argv=args(cmd,true);
- int argc=cmd.size();
-
-#ifndef __APPLE__
- glutInitContextProfile(GLUT_CORE_PROFILE);
-#endif
-
- fpu_trap(false); // Work around FE_INVALID
- glutInit(&argc,argv);
- fpu_trap(settings::trap());
-
- screenWidth=glutGet(GLUT_SCREEN_WIDTH);
- screenHeight=glutGet(GLUT_SCREEN_HEIGHT);
-#endif
-}
-
-void init_osmesa()
-{
-#ifdef HAVE_LIBOSMESA
- // create context and buffer
- if(settings::verbose > 1)
- cout << "Allocating osmesa_buffer of size " << screenWidth << "x"
- << screenHeight << "x4x" << sizeof(GLubyte) << endl;
- osmesa_buffer=new unsigned char[screenWidth*screenHeight*4*sizeof(GLubyte)];
- if(!osmesa_buffer) {
- cerr << "Cannot allocate image buffer." << endl;
- exit(-1);
- }
-
- ctx = OSMesaCreateContextExt(OSMESA_RGBA,16,0,0,NULL);
- if(!ctx) {
- cerr << "OSMesaCreateContext failed." << endl;
- exit(-1);
- }
-
- if(!OSMesaMakeCurrent(ctx,osmesa_buffer,GL_UNSIGNED_BYTE,
- screenWidth,screenHeight )) {
- cerr << "OSMesaMakeCurrent failed." << endl;
- exit(-1);
- }
-
- int z=0, s=0, a=0;
- glGetIntegerv(GL_DEPTH_BITS,&z);
- glGetIntegerv(GL_STENCIL_BITS,&s);
- glGetIntegerv(GL_ACCUM_RED_BITS,&a);
- if(settings::verbose > 1)
- cout << "Offscreen context settings: Depth=" << z << " Stencil=" << s
- << " Accum=" << a << endl;
-
- if(z <= 0) {
- cerr << "Error initializing offscreen context: Depth=" << z << endl;
- exit(-1);
- }
-#endif // HAVE_LIBOSMESA
-}
-
-#endif /* HAVE_GL */
-
-// angle=0 means orthographic.
-void glrender(const string& prefix, const picture *pic, const string& format,
- double width, double height, double angle, double zoom,
- const triple& m, const triple& M, const pair& shift,
- const pair& margin, double *t,
- double *background, size_t nlightsin, triple *lights,
- double *diffuse, double *specular, bool view, int oldpid)
-{
- Iconify=getSetting<bool>("iconify");
-
- if(zoom == 0.0) zoom=1.0;
-
- Prefix=prefix;
- Picture=pic;
- Format=format;
-
- nlights0=nlights=nlightsin;
-
- Lights=lights;
- Diffuse=diffuse;
- Specular=specular;
- View=view;
- Angle=angle*radians;
- Zoom0=zoom;
- Oldpid=oldpid;
- Shift=shift/zoom;
- Margin=margin;
- Background=background;
-
- Xmin=m.getx();
- Xmax=M.getx();
- Ymin=m.gety();
- Ymax=M.gety();
- zmin=m.getz();
- zmax=M.getz();
-
- orthographic=Angle == 0.0;
- H=orthographic ? 0.0 : -tan(0.5*Angle)*zmax;
-
- ignorezoom=false;
- Mode=0;
- Xfactor=Yfactor=1.0;
-
- pair maxtile=getSetting<pair>("maxtile");
- maxTileWidth=(int) maxtile.getx();
- maxTileHeight=(int) maxtile.gety();
- if(maxTileWidth <= 0) maxTileWidth=1024;
- if(maxTileHeight <= 0) maxTileHeight=768;
-
- bool webgl=Format == "html";
-
-#ifdef HAVE_GL
-#ifdef HAVE_PTHREAD
-#ifndef HAVE_LIBOSMESA
- static bool initializedView=false;
-#endif
-#endif
-
-#ifdef HAVE_LIBOSMESA
- if(!webgl) {
- screenWidth=maxTileWidth;
- screenHeight=maxTileHeight;
-
- static bool osmesa_initialized=false;
- if(!osmesa_initialized) {
- osmesa_initialized=true;
- fpu_trap(false); // Work around FE_INVALID.
- init_osmesa();
- fpu_trap(settings::trap());
- }
- }
-#else
- if(glinitialize) {
- if(!webgl) init();
- Fitscreen=1;
- }
-#endif
-#endif
-
- static bool initialized=false;
-
- if(!(initialized && (interact::interactive ||
- getSetting<bool>("animating")))) {
- antialias=getSetting<Int>("antialias") > 1;
- double expand;
- if(webgl)
- expand=1.0;
- else {
- expand=getSetting<double>("render");
- if(expand < 0)
- expand *= (Format.empty() || Format == "eps" || Format == "pdf") ? -2.0 : -1.0;
- if(antialias) expand *= 2.0;
- }
-
- oWidth=width;
- oHeight=height;
- Aspect=width/height;
-
- // Force a hard viewport limit to work around direct rendering bugs.
- // Alternatively, one can use -glOptions=-indirect (with a performance
- // penalty).
- pair maxViewport=getSetting<pair>("maxviewport");
- int maxWidth=maxViewport.getx() > 0 ? (int) ceil(maxViewport.getx()) :
- screenWidth;
- int maxHeight=maxViewport.gety() > 0 ? (int) ceil(maxViewport.gety()) :
- screenHeight;
- if(maxWidth <= 0) maxWidth=max(maxHeight,2);
- if(maxHeight <= 0) maxHeight=max(maxWidth,2);
-
- if(screenWidth <= 0) screenWidth=maxWidth;
- else screenWidth=min(screenWidth,maxWidth);
- if(screenHeight <= 0) screenHeight=maxHeight;
- else screenHeight=min(screenHeight,maxHeight);
-
- fullWidth=(int) ceil(expand*width);
- fullHeight=(int) ceil(expand*height);
-
- if(webgl) {
- Width=fullWidth;
- Height=fullHeight;
- } else {
- Width=min(fullWidth,screenWidth);
- Height=min(fullHeight,screenHeight);
-
- if(Width > Height*Aspect)
- Width=min((int) (ceil(Height*Aspect)),screenWidth);
- else
- Height=min((int) (ceil(Width/Aspect)),screenHeight);
- }
-
- home(webgl);
- setProjection();
- if(webgl) return;
-
- ArcballFactor=1+8.0*hypot(Margin.getx(),Margin.gety())/hypot(Width,Height);
-
-#ifdef HAVE_GL
- for(int i=0; i < 16; ++i)
- T[i]=t[i];
-
- Aspect=((double) Width)/Height;
-
- if(maxTileWidth <= 0) maxTileWidth=screenWidth;
- if(maxTileHeight <= 0) maxTileHeight=screenHeight;
-#ifdef HAVE_LIBGLUT
- setosize();
-#endif
-
- if(View && settings::verbose > 1)
- cout << "Rendering " << stripDir(prefix) << " as "
- << Width << "x" << Height << " image" << endl;
-#endif
- }
-
-#ifdef HAVE_GL
- bool havewindow=initialized && glthread;
-
-#ifndef HAVE_LIBOSMESA
-#ifdef HAVE_LIBGLUT
- unsigned int displaymode=GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH;
-#endif
-
-#ifdef __APPLE__
- displaymode |= GLUT_3_2_CORE_PROFILE;
-#endif
-#endif
-
- camp::clearMaterialBuffer();
-
-#ifndef HAVE_LIBOSMESA
-
-#ifdef HAVE_PTHREAD
- if(glthread && initializedView) {
- if(View) {
-#ifdef __MSDOS__ // Signals are unreliable in MSWindows
- glupdate=true;
-#else
- pthread_kill(mainthread,SIGUSR1);
-#endif
- } else readyAfterExport=queueExport=true;
- return;
- }
-#endif
-
-#ifdef HAVE_LIBGLUT
- if(View) {
- int x,y;
- if(havewindow)
- glutDestroyWindow(window);
-
- windowposition(x,y);
- glutInitWindowPosition(x,y);
- glutInitWindowSize(1,1);
- Int multisample=getSetting<Int>("multisample");
- if(multisample <= 1) multisample=0;
- if(multisample)
- displaymode |= GLUT_MULTISAMPLE;
- glutInitDisplayMode(displaymode);
-
- int samples;
-
-#ifdef FREEGLUT
-#ifdef GLUT_INIT_MAJOR_VERSION
- while(true) {
- if(multisample > 0)
- glutSetOption(GLUT_MULTISAMPLE,multisample);
-#endif
-#endif
- string title=string(settings::PROGRAM)+": "+prefix;
- fpu_trap(false); // Work around FE_INVALID
- window=glutCreateWindow(title.c_str());
- fpu_trap(settings::trap());
-
- GLint samplebuf[1];
- glGetIntegerv(GL_SAMPLES,samplebuf);
- samples=samplebuf[0];
-#ifdef FREEGLUT
-#ifdef GLUT_INIT_MAJOR_VERSION
- if(samples < multisample) {
- multisample=floorpow2(multisample-1);
- if(multisample > 1) {
- glutReshapeWindow(1,1);
- glutDisplayFunc(destroywindow);
- glutShowWindow();
- glutMainLoopEvent();
- continue;
- }
- }
- break;
- }
-#endif
-#endif
- if(settings::verbose > 1 && samples > 1)
- cout << "Multisampling enabled with sample width " << samples
- << endl;
- glutDisplayFunc(display);
- glutShowWindow();
- } else if(!havewindow) {
- glutInitWindowSize(maxTileWidth,maxTileHeight);
- glutInitDisplayMode(displaymode);
- fpu_trap(false); // Work around FE_INVALID
- window=glutCreateWindow("");
- fpu_trap(settings::trap());
- glutHideWindow();
- }
-#endif // HAVE_LIBGLUT
-#endif // HAVE_LIBOSMESA
-
- initialized=true;
-
- GLint val;
- glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE,&val);
- Maxmaterials=val/sizeof(Material);
- if(nmaterials > Maxmaterials) nmaterials=Maxmaterials;
-
- if(glinitialize) {
- glinitialize=false;
- int result = glewInit();
-
- if (result != GLEW_OK) {
- cerr << "GLEW initialization error." << endl;
- exit(-1);
- }
-
- initShaders();
- setBuffers();
- }
-
- glClearColor(Background[0],Background[1],Background[2],Background[3]);
-
-#ifdef HAVE_LIBGLUT
-#ifndef HAVE_LIBOSMESA
- Animate=getSetting<bool>("autoplay") && glthread;
-
- if(View) {
- if(!getSetting<bool>("fitscreen"))
- Fitscreen=0;
- firstFit=true;
- fitscreen();
- setosize();
- }
-#endif
-#endif
-
- glEnable(GL_BLEND);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
-
- glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
- mode();
-
-#ifdef HAVE_LIBOSMESA
- View=false;
-#endif
-
- if(View) {
-#ifdef HAVE_LIBGLUT
-#ifdef HAVE_PTHREAD
-#ifndef HAVE_LIBOSMESA
- initializedView=true;
-#endif
-#endif
- glutReshapeFunc(reshape);
- glutKeyboardFunc(keyboard);
- glutMouseFunc(mouse);
- glutDisplayFunc(display);
-
-#ifdef __MSDOS__
- if(glthread && interact::interactive)
- poll(0);
-#endif
-
- glutMainLoop();
-#endif // HAVE_LIBGLUT
- } else {
- if(glthread) {
- if(havewindow) {
- readyAfterExport=true;
-#ifdef HAVE_PTHREAD
- pthread_kill(mainthread,SIGUSR1);
-#endif
- } else {
- initialized=true;
- readyAfterExport=true;
- Signal(SIGUSR1,exportHandler);
- exportHandler();
- }
- } else {
- exportHandler();
- quit();
- }
- }
-
-#endif /* HAVE_GL */
-}
-
-} // namespace gl
-
-#endif
-
-#ifdef HAVE_GL
-
-namespace camp {
-
-string getLightIndex(size_t const& index, string const& fieldName) {
- ostringstream buf;
- buf << "lights[" << index << "]." << fieldName;
- return Strdup(buf.str());
-}
-
-string getCenterIndex(size_t const& index) {
- ostringstream buf;
- buf << "Centers[" << index << "]";
- return Strdup(buf.str());
-}
-
-template<class T>
-void registerBuffer(const std::vector<T>& buffervector, GLuint& bufferIndex,
- bool copy, GLenum type=GL_ARRAY_BUFFER) {
- if(!buffervector.empty()) {
- if(bufferIndex == 0) {
- glGenBuffers(1,&bufferIndex);
- copy=true;
- }
- glBindBuffer(type,bufferIndex);
- if(copy)
- glBufferData(type,buffervector.size()*sizeof(T),
- buffervector.data(),GL_STATIC_DRAW);
- }
-}
-
-void setUniforms(vertexBuffer& data, GLint shader)
-{
- bool normal=shader != pixelShader;
-
- if(shader != gl::lastshader) {
- glUseProgram(shader);
- gl::lastshader=shader;
-
- glUniform1i(glGetUniformLocation(shader,"nlights"),gl::nlights);
-
- for(size_t i=0; i < gl::nlights; ++i) {
- triple Lighti=gl::Lights[i];
- size_t i4=4*i;
- glUniform3f(glGetUniformLocation(shader,
- getLightIndex(i,"direction").c_str()),
- (GLfloat) Lighti.getx(),(GLfloat) Lighti.gety(),
- (GLfloat) Lighti.getz());
-
- glUniform3f(glGetUniformLocation(shader,
- getLightIndex(i,"color").c_str()),
- (GLfloat) gl::Diffuse[i4],(GLfloat) gl::Diffuse[i4+1],
- (GLfloat) gl::Diffuse[i4+2]);
- }
-
-#if HAVE_LIBOPENIMAGEIO
- // textures
- if (settings::getSetting<bool>("envmap")) {
- glActiveTexture(GL_TEXTURE1);
- glBindBuffer(GL_TEXTURE_2D, gl::envMapBuf);
- glUniform1i(glGetUniformLocation(shader, "environmentMap"), 1);
- glActiveTexture(GL_TEXTURE0);
- }
-#endif
- }
-
- GLuint binding=0;
- GLint blockindex=glGetUniformBlockIndex(shader,"MaterialBuffer");
- glUniformBlockBinding(shader,blockindex,binding);
- bool copy=gl::remesh || data.partial || !data.rendered;
- registerBuffer(data.materials,data.materialsBuffer,copy,GL_UNIFORM_BUFFER);
- glBindBufferBase(GL_UNIFORM_BUFFER,binding,data.materialsBuffer);
-
- glUniformMatrix4fv(glGetUniformLocation(shader,"projViewMat"),1,GL_FALSE,
- value_ptr(gl::projViewMat));
-
- glUniformMatrix4fv(glGetUniformLocation(shader,"viewMat"),1,GL_FALSE,
- value_ptr(gl::viewMat));
- if(normal)
- glUniformMatrix3fv(glGetUniformLocation(shader,"normMat"),1,GL_FALSE,
- value_ptr(gl::normMat));
-}
-
-void drawBuffer(vertexBuffer& data, GLint shader)
-{
- if(data.indices.empty()) return;
-
- bool normal=shader != pixelShader;
- bool color=shader == colorShader || shader == transparentShader;
-
- const size_t size=sizeof(GLfloat);
- const size_t intsize=sizeof(GLint);
- const size_t bytestride=color ? sizeof(VertexData) :
- (normal ? sizeof(vertexData) : sizeof(vertexData0));
-
- bool copy=gl::remesh || data.partial || !data.rendered;
- if(color) registerBuffer(data.Vertices,data.VerticesBuffer,copy);
- else if(normal) registerBuffer(data.vertices,data.verticesBuffer,copy);
- else registerBuffer(data.vertices0,data.vertices0Buffer,copy);
-
- registerBuffer(data.indices,data.indicesBuffer,copy,GL_ELEMENT_ARRAY_BUFFER);
-
- camp::setUniforms(data,shader);
-
- data.rendered=true;
-
- glVertexAttribPointer(positionAttrib,3,GL_FLOAT,GL_FALSE,bytestride,
- (void *) 0);
- glEnableVertexAttribArray(positionAttrib);
-
- if(normal && gl::Nlights > 0) {
- glVertexAttribPointer(normalAttrib,3,GL_FLOAT,GL_FALSE,bytestride,
- (void *) (3*size));
- glEnableVertexAttribArray(normalAttrib);
- } else if(!normal) {
- glVertexAttribPointer(widthAttrib,1,GL_FLOAT,GL_FALSE,bytestride,
- (void *) (3*size));
- glEnableVertexAttribArray(widthAttrib);
- }
-
- glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride,
- (void *) ((normal ? 6 : 4)*size));
- glEnableVertexAttribArray(materialAttrib);
-
- if(color) {
- glVertexAttribPointer(colorAttrib,4,GL_UNSIGNED_BYTE,GL_TRUE,bytestride,
- (void *) (6*size+intsize));
- glEnableVertexAttribArray(colorAttrib);
- }
-
- fpu_trap(false); // Work around FE_INVALID
- glDrawElements(data.type,data.indices.size(),GL_UNSIGNED_INT,(void *) 0);
- fpu_trap(settings::trap());
-
- glDisableVertexAttribArray(positionAttrib);
- if(normal && gl::Nlights > 0)
- glDisableVertexAttribArray(normalAttrib);
- if(!normal)
- glDisableVertexAttribArray(widthAttrib);
- glDisableVertexAttribArray(materialAttrib);
- if(color)
- glDisableVertexAttribArray(colorAttrib);
-
- glBindBuffer(GL_UNIFORM_BUFFER,0);
-
- glBindBuffer(GL_ARRAY_BUFFER,0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
-}
-
-void drawMaterial0()
-{
- drawBuffer(material0Data,pixelShader);
- material0Data.clear();
-}
-
-void drawMaterial1()
-{
- drawBuffer(material1Data,materialShader);
- material1Data.clear();
-}
-
-void drawMaterial()
-{
- drawBuffer(materialData,materialShader);
- materialData.clear();
-}
-
-void drawColor()
-{
- drawBuffer(colorData,colorShader);
- colorData.clear();
-}
-
-void drawTriangle()
-{
- drawBuffer(triangleData,transparentShader);
- triangleData.rendered=false; // Force copying of sorted triangles to GPU.
- triangleData.clear();
-}
-
-void drawTransparent()
-{
- sortTriangles();
- glDepthMask(GL_FALSE); // Enable transparency
- drawBuffer(transparentData,transparentShader);
- transparentData.rendered=false; // Force copying of sorted triangles to GPU.
- glDepthMask(GL_TRUE); // Disable transparency
- transparentData.clear();
-}
-
-void drawBuffers()
-{
- drawMaterial0();
- drawMaterial1();
- drawMaterial();
- drawColor();
- drawTriangle();
- drawTransparent();
-}
-
-void clearMaterialBuffer()
-{
- material.clear();
- material.reserve(nmaterials);
- materialMap.clear();
- materialIndex=0;
-
- material0Data.partial=false;
- material1Data.partial=false;
- materialData.partial=false;
- colorData.partial=false;
- triangleData.partial=false;
- transparentData.partial=false;
-}
-
-void setMaterial(vertexBuffer& data, draw_t *draw)
-{
- if(materialIndex >= data.materialTable.size() ||
- data.materialTable[materialIndex] == -1) {
- if(data.materials.size() >= Maxmaterials) {
- data.partial=true;
- (*draw)();
- }
- size_t size0=data.materialTable.size();
- data.materialTable.resize(materialIndex+1);
- for(size_t i=size0; i < materialIndex; ++i)
- data.materialTable[i]=-1;
- data.materialTable[materialIndex]=data.materials.size();
- data.materials.push_back(material[materialIndex]);
- }
- materialIndex=data.materialTable[materialIndex];
-}
-
-}
-#endif /* HAVE_GL */