summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/glrender.cc
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2019-03-27 22:27:57 +0000
committerKarl Berry <karl@freefriends.org>2019-03-27 22:27:57 +0000
commit9121faed0cf54a08882acf41120cf28fc3a32998 (patch)
treefe7f0c5e9ed02fe4a1fc389c27c88750c2807e43 /Build/source/utils/asymptote/glrender.cc
parentb8e24fbf964b4030f68a8484a53d405869693266 (diff)
asy 2.48 sources
git-svn-id: svn://tug.org/texlive/trunk@50622 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/glrender.cc')
-rw-r--r--Build/source/utils/asymptote/glrender.cc556
1 files changed, 282 insertions, 274 deletions
diff --git a/Build/source/utils/asymptote/glrender.cc b/Build/source/utils/asymptote/glrender.cc
index af405d6d853..ab5f1383615 100644
--- a/Build/source/utils/asymptote/glrender.cc
+++ b/Build/source/utils/asymptote/glrender.cc
@@ -14,6 +14,8 @@
#include <sys/time.h>
#include "common.h"
+#include "locate.h"
+#include "seconds.h"
#ifdef HAVE_GL
@@ -43,16 +45,37 @@
#endif
#endif
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+#include "shaders.h"
+#include "material.h"
+
+using settings::locateFile;
+using camp::Material;
+using camp::Maxmaterials;
+using camp::Nmaterials;
+using camp::nmaterials;
+using utils::seconds;
+
namespace camp {
billboard BB;
+GLint noColorShader;
+GLint colorShader;
+size_t Maxmaterials;
+size_t Nmaterials=1;
+size_t nmaterials=48;
}
-
namespace gl {
bool outlinemode=false;
bool glthread=false;
bool initialize=true;
+GLint Maxvertices;
+Int maxvertices;
+
using camp::picture;
using camp::drawRawImage;
using camp::transform;
@@ -65,8 +88,6 @@ using settings::getSetting;
using settings::Setting;
bool Iconify=false;
-bool Menu;
-bool Motion;
bool ignorezoom;
int Fitscreen;
@@ -86,7 +107,6 @@ bool queueScreen=false;
int x0,y0;
string Action;
-int MenuButton;
double lastangle;
Arcball arcball;
@@ -132,21 +152,55 @@ static const double degrees=180.0/pi;
static const double radians=1.0/degrees;
double Background[4];
-size_t Nlights;
+size_t Nlights=1; // Maximum number of lights compiled in shader
+size_t nlights; // Actual number of lights
triple *Lights;
double *Diffuse;
double *Ambient;
double *Specular;
-bool ViewportLighting;
bool antialias;
double Zoom;
double Zoom0;
double lastzoom;
-GLfloat Rotate[16];
-GLUnurbs *nurb=NULL;
+using glm::dvec3;
+using glm::mat4;
+using glm::dmat4;
+using glm::value_ptr;
+using glm::translate;
+
+mat4 projViewMat;
+mat4 viewMat;
+mat4 normMat;
+
+dmat4 dprojMat;
+dmat4 dviewMat;
+dmat4 drotateMat;
+
+ModelView modelView;
+
+void updateModelViewData()
+{
+ // Like Fortran, OpenGL uses transposed (column-major) format!
+ dmat4 MV=glm::transpose(dviewMat);
+ dmat4 MVinv=glm::inverse(MV);
+
+ normMat=mat4(MVinv);
+
+ double* T=value_ptr(MV);
+ double* Tinv=value_ptr(MVinv);
+
+ for(int j=0; j < 16; ++j) {
+ modelView.T[j]=T[j];
+ modelView.Tinv[j]=Tinv[j];
+ }
+}
+
+
+GLint shaderProg,shaderProgColor;
+double *Rotate;
void *glrenderWrapper(void *a);
#ifdef HAVE_LIBOSMESA
@@ -190,51 +244,14 @@ inline T max(T a, T b)
return (a > b) ? a : b;
}
-void lighting()
+glm::vec4 vec4(triple v)
{
- for(size_t i=0; i < Nlights; ++i) {
- GLenum index=GL_LIGHT0+i;
- triple Lighti=Lights[i];
- GLfloat position[]={(GLfloat) Lighti.getx(),(GLfloat) Lighti.gety(),
- (GLfloat) Lighti.getz(),0.0};
- glLightfv(index,GL_POSITION,position);
- }
+ return glm::vec4(v.getx(),v.gety(),v.getz(),0);
}
-void initlighting()
+glm::vec4 vec4(double *v)
{
- glClearColor(Background[0],Background[1],Background[2],Background[3]);
- glEnable(GL_LIGHTING);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,getSetting<bool>("twosided"));
-
- for(size_t i=0; i < Nlights; ++i) {
- GLenum index=GL_LIGHT0+i;
- glEnable(index);
-
- size_t i4=4*i;
-
- GLfloat diffuse[]={(GLfloat) Diffuse[i4],(GLfloat) Diffuse[i4+1],
- (GLfloat) Diffuse[i4+2],(GLfloat) Diffuse[i4+3]};
- glLightfv(index,GL_DIFFUSE,diffuse);
-
- GLfloat ambient[]={(GLfloat) Ambient[i4],(GLfloat) Ambient[i4+1],
- (GLfloat) Ambient[i4+2],(GLfloat) Ambient[i4+3]};
- glLightfv(index,GL_AMBIENT,ambient);
-
- GLfloat specular[]={(GLfloat) Specular[i4],(GLfloat) Specular[i4+1],
- (GLfloat) Specular[i4+2],(GLfloat) Specular[i4+3]};
- glLightfv(index,GL_SPECULAR,specular);
- }
-
- static size_t lastNlights=0;
- for(size_t i=Nlights; i < lastNlights; ++i) {
- GLenum index=GL_LIGHT0+i;
- glDisable(index);
- }
- lastNlights=Nlights;
-
- if(ViewportLighting)
- lighting();
+ return glm::vec4(v[0],v[1],v[2],v[3]);
}
void setDimensions(int Width, int Height, double X, double Y)
@@ -275,16 +292,26 @@ void setDimensions(int Width, int Height, double X, double Y)
}
}
+void frustum(GLdouble left, GLdouble right, GLdouble bottom,
+ GLdouble top, GLdouble nearVal, GLdouble farVal)
+{
+ dprojMat=glm::frustum(left,right,bottom,top,nearVal,farVal);
+ projViewMat=mat4(dprojMat*dviewMat);
+}
+
+void ortho(GLdouble left, GLdouble right, GLdouble bottom,
+ GLdouble top, GLdouble nearVal, GLdouble farVal)
+{
+ dprojMat=glm::ortho(left,right,bottom,top,nearVal,farVal);
+ projViewMat=mat4(dprojMat*dviewMat);
+}
+
void setProjection()
{
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
setDimensions(Width,Height,X,Y);
- if(orthographic)
- glOrtho(xmin,xmax,ymin,ymax,-zmax,-zmin);
- else
- glFrustum(xmin,xmax,ymin,ymax,-zmax,-zmin);
- glMatrixMode(GL_MODELVIEW);
+ if(orthographic) ortho(xmin,xmax,ymin,ymax,-zmax,-zmin);
+ else frustum(xmin,xmax,ymin,ymax,-zmax,-zmin);
+
#ifdef HAVE_LIBGLUT
double arcballRadius=getSetting<double>("arcballradius");
arcball.set_params(vec2(0.5*Width,0.5*Height),arcballRadius*Zoom);
@@ -304,9 +331,6 @@ void drawscene(double Width, double Height)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- if(!ViewportLighting)
- lighting();
-
triple m(xmin,ymin,zmin);
triple M(xmax,ymax,zmax);
double perspective=orthographic ? 0.0 : 1.0/zmax;
@@ -314,13 +338,13 @@ void drawscene(double Width, double Height)
double size2=hypot(Width,Height);
// Render opaque objects
- Picture->render(nurb,size2,m,M,perspective,Nlights,false);
+ Picture->render(size2,m,M,perspective,false);
// Enable transparency
glDepthMask(GL_FALSE);
// Render transparent objects
- Picture->render(nurb,size2,m,M,perspective,Nlights,true);
+ Picture->render(size2,m,M,perspective,true);
glDepthMask(GL_TRUE);
}
@@ -416,11 +440,18 @@ void home()
arcball.init();
}
#endif
- glLoadIdentity();
- glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
+ viewMat=mat4(1.0f);
+ normMat=mat4(1.0f);
+
+ dviewMat=dmat4(1.0);
+ drotateMat=dmat4(1.0);
+
+ Rotate=value_ptr(drotateMat);
+ updateModelViewData();
+
lastzoom=Zoom=Zoom0;
setDimensions(Width,Height,0,0);
- initlighting();
+ glClearColor(Background[0],Background[1],Background[2],Background[3]);
}
void nodisplay()
@@ -479,24 +510,17 @@ void mode()
{
switch(Mode) {
case 0:
- for(size_t i=0; i < Nlights; ++i)
- glEnable(GL_LIGHT0+i);
outlinemode=false;
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
- gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_FILL);
++Mode;
break;
case 1:
- for(size_t i=0; i < Nlights; ++i)
- glDisable(GL_LIGHT0+i);
outlinemode=true;
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
- gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_OUTLINE_PATCH);
++Mode;
break;
case 2:
outlinemode=false;
- gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON);
Mode=0;
break;
}
@@ -647,7 +671,18 @@ void display()
if(!Animate) screen();
queueScreen=false;
}
+
+ maxvertices=getSetting<Int>("maxvertices");
+ if(maxvertices == 0) maxvertices=Maxvertices;
+
+ bool fps=settings::verbose > 2;
+ if(fps) seconds();
drawscene(Width,Height);
+ if(fps) {
+ double s=seconds();
+ if(s > 0.0)
+ cout << "FPS=" << 1.0/s << endl;
+ }
glutSwapBuffers();
#ifdef HAVE_PTHREAD
if(glthread && Animate) {
@@ -686,10 +721,13 @@ void update()
lastzoom=Zoom;
glLoadIdentity();
double cz=0.5*(zmin+zmax);
- glTranslatef(cx,cy,cz);
- glMultMatrixf(Rotate);
- glTranslatef(0,0,-cz);
+
+ dviewMat=translate(translate(dmat4(1.0),dvec3(cx,cy,cz))*drotateMat,
+ dvec3(0,0,-cz));
+ viewMat=mat4(dviewMat);
setProjection();
+ updateModelViewData();
+
glutPostRedisplay();
}
@@ -766,30 +804,10 @@ void capzoom()
}
-int menustatus=GLUT_MENU_NOT_IN_USE;
-
-void menuStatus(int status, int x, int y)
-{
- menustatus=status;
-}
-
-void disableMenu()
-{
- Menu=false;
- if(menustatus == GLUT_MENU_NOT_IN_USE)
- glutDetachMenu(MenuButton);
-}
-
void zoom(int x, int y)
{
if(ignorezoom) {ignorezoom=false; y0=y; return;}
if(x > 0 && y > 0) {
- if(Menu) {
- disableMenu();
- y0=y;
- return;
- }
- Motion=true;
double zoomFactor=getSetting<double>("zoomfactor");
if(zoomFactor > 0.0) {
double zoomStep=getSetting<double>("zoomstep");
@@ -825,21 +843,15 @@ void mousewheel(int wheel, int direction, int x, int y)
void rotate(int x, int y)
{
if(x > 0 && y > 0) {
- if(Menu) {
- disableMenu();
- arcball.mouse_down(x,Height-y);
- return;
- }
- Motion=true;
arcball.mouse_motion(x,Height-y,0,
Action == "rotateX", // X rotation only
Action == "rotateY"); // Y rotation only
for(int i=0; i < 4; ++i) {
- const vec4& roti=arcball.rot[i];
+ const ::vec4& roti=arcball.rot[i];
int i4=4*i;
for(int j=0; j < 4; ++j)
- Rotate[i4+j]=roti[j];
+ value_ptr(drotateMat)[i4+j]=roti[j];
}
update();
@@ -853,9 +865,10 @@ double Degrees(int x, int y)
void updateArcball()
{
+ Rotate=value_ptr(drotateMat);
for(int i=0; i < 4; ++i) {
int i4=4*i;
- vec4& roti=arcball.rot[i];
+ ::vec4& roti=arcball.rot[i];
for(int j=0; j < 4; ++j)
roti[j]=Rotate[i4+j];
}
@@ -864,39 +877,31 @@ void updateArcball()
void rotateX(double step)
{
- glLoadIdentity();
- glRotatef(step,1,0,0);
- glMultMatrixf(Rotate);
- glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
+ dmat4 tmpRot(1.0);
+ tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(1,0,0));
+ drotateMat=tmpRot*drotateMat;
updateArcball();
}
void rotateY(double step)
{
- glLoadIdentity();
- glRotatef(step,0,1,0);
- glMultMatrixf(Rotate);
- glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
+ dmat4 tmpRot(1.0);
+ tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(0,1,0));
+ drotateMat=tmpRot*drotateMat;
updateArcball();
}
void rotateZ(double step)
{
- glLoadIdentity();
- glRotatef(step,0,0,1);
- glMultMatrixf(Rotate);
- glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
+ dmat4 tmpRot(1.0);
+ tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(0,0,1));
+ drotateMat=tmpRot*drotateMat;
updateArcball();
}
void rotateZ(int x, int y)
{
if(x > 0 && y > 0) {
- if(Menu) {
- disableMenu();
- return;
- }
- Motion=true;
double angle=Degrees(x,y);
rotateZ(angle-lastangle);
lastangle=angle;
@@ -971,7 +976,6 @@ string action(int button, int mod)
void timeout(int)
{
- if(Menu) disableMenu();
}
void mouse(int button, int state, int x, int y)
@@ -979,19 +983,6 @@ void mouse(int button, int state, int x, int y)
int mod=glutGetModifiers();
string Action=action(button,mod);
- if(!Menu) {
- if(mod == 0 && state == GLUT_UP && !Motion && Action == "zoom/menu") {
- MenuButton=button;
- glutMotionFunc(NULL);
- glutTimerFunc(getSetting<Int>("doubleclick"),timeout,0);
- glutAttachMenu(button);
- Menu=true;
- return;
- } else Motion=false;
- }
-
- disableMenu();
-
if(Action == "zoomin") {
glutMotionFunc(NULL);
mousewheel(0,1,x,y);
@@ -1188,64 +1179,6 @@ void keyboard(unsigned char key, int x, int y)
}
}
-enum Menu {HOME,FITSCREEN,XSPIN,YSPIN,ZSPIN,STOP,MODE,EXPORT,CAMERA,
- PLAY,STEP,REVERSE,QUIT};
-
-void menu(int choice)
-{
- if(Menu) disableMenu();
- ignorezoom=true;
- Motion=true;
- switch (choice) {
- case HOME: // Home
- home();
- update();
- break;
- case FITSCREEN:
- togglefitscreen();
- break;
- case XSPIN:
- spinx();
- break;
- case YSPIN:
- spiny();
- break;
- case ZSPIN:
- spinz();
- break;
- case STOP:
- idle();
- break;
- case MODE:
- mode();
- break;
- case EXPORT:
- queueExport=true;
- break;
- case CAMERA:
- showCamera();
- break;
- case PLAY:
- if(getSetting<bool>("reverse")) Animate=false;
- Setting("reverse")=Step=false;
- animate();
- break;
- case REVERSE:
- if(!getSetting<bool>("reverse")) Animate=false;
- Setting("reverse")=true;
- Step=false;
- animate();
- break;
- case STEP:
- Step=true;
- animate();
- break;
- case QUIT:
- quit();
- break;
- }
-}
-
void setosize()
{
oldWidth=(int) ceil(oWidth);
@@ -1328,10 +1261,17 @@ void init()
push_split(cmd,getSetting<string>("glOptions"));
char **argv=args(cmd,true);
int argc=cmd.size();
+
+// glutInitContextVersion(4,3);
+ glutInitContextProfile(GLUT_CORE_PROFILE);
+ //glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
+
glutInit(&argc,argv);
-
+ // NOTE: Change version if needed.
+
screenWidth=glutGet(GLUT_SCREEN_WIDTH);
screenHeight=glutGet(GLUT_SCREEN_HEIGHT);
+
#endif
}
@@ -1375,21 +1315,74 @@ void init_osmesa()
#endif // HAVE_LIBOSMESA
}
+GLuint vertShader,fragShader;
+GLuint vertShaderCol,fragShaderCol;
+
+void initshader()
+{
+ Nlights=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);
+ }
+
+ vertShader=createShaderFile(vs.c_str(),GL_VERTEX_SHADER,Nlights,
+ Nmaterials);
+ fragShader=createShaderFile(fs.c_str(),GL_FRAGMENT_SHADER,Nlights,
+ Nmaterials);
+ glAttachShader(shaderProg,vertShader);
+ glAttachShader(shaderProg,fragShader);
+
+ shaderProgColor=glCreateProgram();
+ vertShaderCol=createShaderFile(vs.c_str(),
+ GL_VERTEX_SHADER,Nlights,Nmaterials,
+ {"EXPLICIT_COLOR"});
+ fragShaderCol=createShaderFile(fs.c_str(),
+ GL_FRAGMENT_SHADER,Nlights,Nmaterials,
+ {"EXPLICIT_COLOR"});
+ glAttachShader(shaderProgColor,vertShaderCol);
+ glAttachShader(shaderProgColor,fragShaderCol);
+
+ camp::noColorShader=shaderProg;
+ camp::colorShader=shaderProgColor;
+
+ glLinkProgram(shaderProg);
+ glDetachShader(shaderProg,vertShader);
+ glDetachShader(shaderProg,fragShader);
+ glDeleteShader(vertShader);
+ glDeleteShader(fragShader);
+
+ glLinkProgram(shaderProgColor);
+ glDetachShader(shaderProgColor,vertShaderCol);
+ glDetachShader(shaderProgColor,fragShaderCol);
+ glDeleteShader(vertShaderCol);
+ glDeleteShader(fragShaderCol);
+}
+
+void deleteshader()
+{
+ glDeleteProgram(camp::noColorShader);
+ glDeleteProgram(camp::colorShader);
+}
+
// 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, double *t,
- double *background, size_t nlights, triple *lights,
+ double *background, size_t nlights0, triple *lights,
double *diffuse, double *ambient, double *specular,
- bool Viewportlighting, bool view, int oldpid)
+ bool view, int oldpid)
{
bool offscreen=getSetting<bool>("offscreen");
Iconify=getSetting<bool>("iconify");
-
+
#ifdef HAVE_PTHREAD
static bool initializedView=false;
#endif
-
width=max(width,1.0);
height=max(height,1.0);
@@ -1403,12 +1396,12 @@ void glrender(const string& prefix, const picture *pic, const string& format,
for(int i=0; i < 4; ++i)
Background[i]=background[i];
- Nlights=min(nlights,(size_t) GL_MAX_LIGHTS);
+ nlights=min(nlights0,(size_t) GL_MAX_LIGHTS);
+
Lights=lights;
Diffuse=diffuse;
Ambient=ambient;
Specular=specular;
- ViewportLighting=Viewportlighting;
View=view;
Angle=angle*radians;
Zoom0=zoom;
@@ -1425,8 +1418,6 @@ void glrender(const string& prefix, const picture *pic, const string& format,
orthographic=Angle == 0.0;
H=orthographic ? 0.0 : -tan(0.5*Angle)*zmax;
- Menu=false;
- Motion=true;
ignorezoom=false;
Mode=0;
Xfactor=Yfactor=1.0;
@@ -1499,7 +1490,7 @@ void glrender(const string& prefix, const picture *pic, const string& format,
setosize();
#endif
- if(View && settings::verbose > 1)
+ if(View && settings::verbose > 1)
cout << "Rendering " << stripDir(prefix) << " as "
<< Width << "x" << Height << " image" << endl;
}
@@ -1508,12 +1499,11 @@ void glrender(const string& prefix, const picture *pic, const string& format,
#ifdef HAVE_LIBGLUT
unsigned int displaymode=GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH;
-
- int buttons[]={GLUT_LEFT_BUTTON,GLUT_MIDDLE_BUTTON,GLUT_RIGHT_BUTTON};
string buttonnames[]={"left","middle","right"};
- size_t nbuttons=sizeof(buttons)/sizeof(int);
#endif
+ camp::clearMaterialBuffer();
+
#ifdef HAVE_PTHREAD
if(glthread && initializedView && !offscreen) {
if(!View)
@@ -1541,6 +1531,7 @@ void glrender(const string& prefix, const picture *pic, const string& format,
ostringstream buf;
int samples;
+
#ifdef FREEGLUT
#ifdef GLUT_INIT_MAJOR_VERSION
while(true) {
@@ -1549,27 +1540,8 @@ void glrender(const string& prefix, const picture *pic, const string& format,
#endif
#endif
string title=string(settings::PROGRAM)+": "+prefix;
- string suffix;
- for(size_t i=0; i < nbuttons; ++i) {
- int button=buttons[i];
- if(action(button,0) == "zoom/menu") {
- suffix="Double click "+buttonnames[i]+" button for menu";
- break;
- }
- }
- if(suffix.empty()) {
- for(size_t i=0; i < nbuttons; ++i) {
- int button=buttons[i];
- if(action(button,0) == "menu") {
- suffix="Click "+buttonnames[i]+" button for menu";
- break;
- }
- }
- }
-
- title += " ["+suffix+"]";
-
window=glutCreateWindow(title.c_str());
+
GLint samplebuf[1];
glGetIntegerv(GL_SAMPLES,samplebuf);
samples=samplebuf[0];
@@ -1603,9 +1575,23 @@ void glrender(const string& prefix, const picture *pic, const string& format,
}
#endif // HAVE_LIBGLUT
initialized=true;
+
+ glewExperimental = GL_TRUE;
+
+ int result = glewInit();
+
+ if (result != GLEW_OK) {
+ cerr << "GLEW initialization error." << endl;
+ exit(-1);
+ }
- glMatrixMode(GL_MODELVIEW);
-
+ GLint val;
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE,&val);
+ Maxmaterials=val/sizeof(Material);
+ if(nmaterials > Maxmaterials) nmaterials=Maxmaterials;
+
+ glGetIntegerv(GL_MAX_ELEMENTS_VERTICES,&Maxvertices);
+
home();
#ifdef HAVE_LIBGLUT
@@ -1620,35 +1606,13 @@ void glrender(const string& prefix, const picture *pic, const string& format,
}
}
#endif
+
+ initshader();
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
- glEnable(GL_MAP1_VERTEX_3);
- glEnable(GL_MAP1_VERTEX_4);
- glEnable(GL_MAP2_VERTEX_3);
- glEnable(GL_MAP2_VERTEX_4);
- glEnable(GL_MAP2_COLOR_4);
-
+
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
-
- if(nurb == NULL) {
- nurb=gluNewNurbsRenderer();
- if(nurb == NULL)
- outOfMemory();
- gluNurbsProperty(nurb,GLU_SAMPLING_METHOD,GLU_PARAMETRIC_ERROR);
- gluNurbsProperty(nurb,GLU_SAMPLING_TOLERANCE,0.5);
- gluNurbsProperty(nurb,GLU_PARAMETRIC_TOLERANCE,1.0);
- gluNurbsProperty(nurb,GLU_CULLING,GLU_TRUE);
-
- // The callback tessellation algorithm avoids artifacts at degenerate
- // control points.
- gluNurbsProperty(nurb,GLU_NURBS_MODE,GLU_NURBS_TESSELLATOR);
- gluNurbsCallback(nurb,GLU_NURBS_BEGIN,(_GLUfuncptr) glBegin);
- gluNurbsCallback(nurb,GLU_NURBS_VERTEX,(_GLUfuncptr) glVertex3fv);
- gluNurbsCallback(nurb,GLU_NURBS_END,(_GLUfuncptr) glEnd);
- gluNurbsCallback(nurb,GLU_NURBS_COLOR,(_GLUfuncptr) glColor4fv);
- }
-
mode();
if(View && !offscreen) {
@@ -1660,28 +1624,6 @@ void glrender(const string& prefix, const picture *pic, const string& format,
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
- glutCreateMenu(menu);
- glutAddMenuEntry("(h) Home",HOME);
- glutAddMenuEntry("(f) Fitscreen",FITSCREEN);
- glutAddMenuEntry("(x) X spin",XSPIN);
- glutAddMenuEntry("(y) Y spin",YSPIN);
- glutAddMenuEntry("(z) Z spin",ZSPIN);
- glutAddMenuEntry("(s) Stop",STOP);
- glutAddMenuEntry("(m) Mode",MODE);
- glutAddMenuEntry("(e) Export",EXPORT);
- glutAddMenuEntry("(c) Camera",CAMERA);
- glutAddMenuEntry("(p) Play",PLAY);
- glutAddMenuEntry("(r) Reverse",REVERSE);
- glutAddMenuEntry("( ) Step",STEP);
- glutAddMenuEntry("(q) Quit" ,QUIT);
- glutMenuStatusFunc(menuStatus);
-
- for(size_t i=0; i < nbuttons; ++i) {
- int button=buttons[i];
- if(action(button,0) == "menu")
- glutAttachMenu(button);
- }
-
glutMainLoop();
#endif // HAVE_LIBGLUT
} else {
@@ -1706,4 +1648,70 @@ void glrender(const string& prefix, const picture *pic, const string& format,
} // namespace gl
+namespace camp {
+
+std::string getMaterialIndex(size_t const& index,
+ std::string const& fieldName)
+{
+ return "materials["+std::to_string(index)+"]."+fieldName;
+}
+
+std::string getLightIndex(size_t const& index, std::string const& fieldName) {
+ return "lights["+std::to_string(index)+"]."+fieldName;
+}
+
+void setUniforms(GLint shader)
+{
+ if(gl::nlights > gl::Nlights || nmaterials > Nmaterials) {
+ gl::deleteshader();
+ gl::initshader();
+ }
+
+ glUseProgram(shader);
+
+ glUniformMatrix4fv(glGetUniformLocation(shader,"projViewMat"),1,GL_FALSE, value_ptr(gl::projViewMat));
+ glUniformMatrix4fv(glGetUniformLocation(shader,"viewMat"),1,GL_FALSE, value_ptr(gl::viewMat));
+ glUniformMatrix4fv(glGetUniformLocation(shader,"normMat"),1,GL_FALSE, value_ptr(gl::normMat));
+
+ GLuint binding=0;
+ GLint blockindex=glGetUniformBlockIndex(shader,"MaterialBuffer");
+ glUniformBlockBinding(shader,blockindex,binding);
+
+ GLuint ubo;
+ glGenBuffers(1,&ubo);
+ glBindBuffer(GL_UNIFORM_BUFFER,ubo);
+
+ glBufferData(GL_UNIFORM_BUFFER,drawElement::material.size()*sizeof(Material),
+ drawElement::material.data(),GL_STATIC_DRAW);
+ glBindBufferBase(GL_UNIFORM_BUFFER,binding,ubo);
+
+ 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;
+ glUniform4f(glGetUniformLocation(shader,
+ getLightIndex(i,"direction").c_str()),
+ (GLfloat) Lighti.getx(),(GLfloat) Lighti.gety(),
+ (GLfloat) Lighti.getz(),0.0);
+
+ glUniform4f(glGetUniformLocation(shader,
+ getLightIndex(i,"diffuse").c_str()),
+ (GLfloat) gl::Diffuse[i4],(GLfloat) gl::Diffuse[i4+1],
+ (GLfloat) gl::Diffuse[i4+2],(GLfloat) gl::Diffuse[i4+3]);
+
+ glUniform4f(glGetUniformLocation(shader,
+ getLightIndex(i,"ambient").c_str()),
+ (GLfloat) gl::Ambient[i4],(GLfloat) gl::Ambient[i4+1],
+ (GLfloat) gl::Ambient[i4+2],(GLfloat) gl::Ambient[i4+3]);
+
+ glUniform4f(glGetUniformLocation(shader,
+ getLightIndex(i,"specular").c_str()),
+ (GLfloat) gl::Specular[i4],(GLfloat) gl::Specular[i4+1],
+ (GLfloat) gl::Specular[i4+2],(GLfloat) gl::Specular[i4+3]);
+ }
+}
+
+}
+
#endif