aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/displaywindow.c807
-rw-r--r--src/glbits.c814
-rw-r--r--src/glbits.h31
4 files changed, 858 insertions, 796 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b303a24..759a667 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,7 @@
bin_PROGRAMS = dtr
dtr_SOURCES = main.c displaywindow.c trackball.c reflections.c readpng.c mrc.c imagedisplay.c utils.c itrans.c qdrp.c cache.c \
itrans-threshold.c itrans-zaefferer.c itrans-stat.c control.c mapping.c reproject.c prealign.c basis.c \
- dirax.c image.c refine.c gtk-valuegraph.c intensities.c
+ dirax.c image.c refine.c gtk-valuegraph.c intensities.c glbits.c
dtr_LDADD = @LIBS@ @GTK_LIBS@ -lm @GTKGLEXT_LIBS@ -lgsl -lgslcblas -lutil
AM_CFLAGS = -Wall -g @CFLAGS@ @GTK_CFLAGS@ @GTKGLEXT_CFLAGS@
AM_CPPFLAGS = -DDATADIR=\""$(datadir)"\"
diff --git a/src/displaywindow.c b/src/displaywindow.c
index 721c069..46b4822 100644
--- a/src/displaywindow.c
+++ b/src/displaywindow.c
@@ -37,26 +37,7 @@
#include "refine.h"
#include "imagedisplay.h"
#include "intensities.h"
-
-static void displaywindow_gl_set_ortho(DisplayWindow *dw, GLfloat w, GLfloat h) {
-
- GLfloat aspect = w/h;
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(-aspect*(dw->distance/2.0), aspect*(dw->distance/2.0), -(dw->distance/2.0), (dw->distance/2.0), 0.001, 400.0);
- glMatrixMode(GL_MODELVIEW);
-
-}
-
-static void displaywindow_gl_set_perspective(DisplayWindow *dw, GLfloat w, GLfloat h) {
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(50.0, w/h, 0.001, 400.0);
- glMatrixMode(GL_MODELVIEW);
-
-}
+#include "glbits.h"
static gint displaywindow_changeview(GtkWidget *widget, GtkRadioAction *action, DisplayWindow *dw) {
@@ -65,9 +46,9 @@ static gint displaywindow_changeview(GtkWidget *widget, GtkRadioAction *action,
dw->view = gtk_radio_action_get_current_value(action);
if ( dw->view == DW_ORTHO ) {
- displaywindow_gl_set_ortho(dw, w, h);
+ glbits_set_ortho(dw, w, h);
} else {
- displaywindow_gl_set_perspective(dw, w, h);
+ glbits_set_perspective(dw, w, h);
}
return 0;
@@ -103,9 +84,9 @@ static gint displaywindow_gl_motion_notify(GtkWidget *widget, GdkEventMotion *ev
if ( dw->distance < 1.0 ) dw->distance = 1.0;
if ( dw->distance > 310.0 ) dw->distance = 310.0;
if ( dw->view == DW_ORTHO ) {
- displaywindow_gl_set_ortho(dw, w, h);
+ glbits_set_ortho(dw, w, h);
} else {
- displaywindow_gl_set_perspective(dw, w, h);
+ glbits_set_perspective(dw, w, h);
}
} else if ( event->state & GDK_SHIFT_MASK ) {
@@ -130,714 +111,6 @@ static gint displaywindow_gl_motion_notify(GtkWidget *widget, GdkEventMotion *ev
}
-#define BLOB_BITS 5
-#define VERTICES_IN_A_BLOB 4*BLOB_BITS*BLOB_BITS*2
-#define ADD_VERTEX \
- vertices[3*i + 0] = reflection->x/1e9 + size*xv; \
- vertices[3*i + 1] = reflection->y/1e9 + size*yv; \
- vertices[3*i + 2] = reflection->z/1e9 + size*zv; \
- normals[3*i + 0] = xv; \
- normals[3*i + 1] = yv; \
- normals[3*i + 2] = zv; \
- i++;
-
-#define DRAW_BLOB \
- double step = M_PI/(double)BLOB_BITS; \
- int is, js; \
- for ( is=0; is<BLOB_BITS; is++ ) { \
- for ( js=0; js<BLOB_BITS*2; js++ ) { \
- double theta, phi; \
- GLfloat xv, yv, zv; \
- theta = (M_PI/(double)BLOB_BITS) * (double)js; \
- phi = (M_PI/(double)BLOB_BITS) * (double)is; \
- xv = sin(theta)*sin(phi); \
- yv = cos(phi); \
- zv = cos(theta)*sin(phi); \
- ADD_VERTEX \
- xv = sin(theta)*sin(phi+step); \
- yv = cos(phi+step); \
- zv = cos(theta)*sin(phi+step); \
- ADD_VERTEX \
- xv = sin(theta+step)*sin(phi+step); \
- yv = cos(phi+step); \
- zv = cos(theta+step)*sin(phi+step); \
- ADD_VERTEX \
- xv = sin(theta+step)*sin(phi); \
- yv = cos(phi); \
- zv = cos(theta+step)*sin(phi); \
- ADD_VERTEX \
- } \
- }
-
-#define DRAW_POINTER_LINE \
- glBegin(GL_LINES); \
- glVertex3f(1.0, 0.0, 0.0); \
- glVertex3f(0.0, 0.0, 0.0); \
- glEnd();
-
-#define DRAW_POINTER_HEAD \
- glPushMatrix(); \
- for ( pointer_head_face = 1; pointer_head_face <= 4; pointer_head_face++ ) { \
- glRotatef(90.0, 1.0, 0.0, 0.0); \
- glBegin(GL_TRIANGLES); \
- /* One face */ \
- glNormal3f(0.2, 0.8, 0.0); \
- glVertex3f(1.0, 0.0, 0.0); \
- glVertex3f(0.8, 0.2, 0.2); \
- glVertex3f(0.8, 0.2, -0.2); \
- /* One quarter of the "bottom square" */ \
- glNormal3f(1.0, 0.0, 0.0); \
- glVertex3f(0.8, 0.2, 0.2); \
- glVertex3f(0.8, 0.2, -0.2); \
- glVertex3f(0.8, 0.0, 0.0); \
- glEnd(); \
- } \
- glPopMatrix();
-
-static void displaywindow_gl_prepare(DisplayWindow *dw) {
-
- GLfloat bblue[] = { 0.0, 0.0, 1.0, 1.0 };
- GLfloat blue[] = { 0.0, 0.0, 0.5, 1.0 };
- GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };
- GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 };
- GLfloat yellow[] = { 1.0, 1.0, 0.0, 1.0 };
- GLfloat glass[] = { 0.2, 0.0, 0.8, 000.1 };
- GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
- Reflection *reflection;
- int i;
- ControlContext *ctx;
- GLfloat *vertices;
- GLfloat *normals;
-
- ctx = dw->ctx;
-
- /* "Measured" reflections */
- if ( dw->gl_use_buffers ) {
- glGenBuffersARB(1, &dw->gl_ref_vertex_buffer);
- glGenBuffersARB(1, &dw->gl_ref_normal_buffer);
- }
- reflection = ctx->reflectionlist->reflections;
- i = 0;
- while ( reflection != NULL ) {
- if ( reflection->type == REFLECTION_NORMAL ) i++;
- reflection = reflection->next;
- };
- dw->gl_ref_num_vertices = i;
- if ( dw->gl_ref_num_vertices ) {
- i = 0;
- reflection = ctx->reflectionlist->reflections;
- vertices = malloc(3*dw->gl_ref_num_vertices*sizeof(GLfloat));
- normals = malloc(3*dw->gl_ref_num_vertices*sizeof(GLfloat));
- while ( reflection != NULL ) {
- if ( reflection->type == REFLECTION_NORMAL ) {
- vertices[3*i + 0] = reflection->x/1e9;
- vertices[3*i + 1] = reflection->y/1e9;
- vertices[3*i + 2] = reflection->z/1e9;
- normals[3*i + 0] = reflection->x/1e9;
- normals[3*i + 1] = reflection->y/1e9;
- normals[3*i + 2] = reflection->z/1e9;
- i++;
- }
- reflection = reflection->next;
- };
- if ( dw->gl_use_buffers ) {
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_vertex_buffer);
- glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_ref_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
- free(vertices);
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_normal_buffer);
- glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_ref_num_vertices*sizeof(GLfloat), normals, GL_STATIC_DRAW);
- free(normals);
- } else {
- dw->gl_ref_vertex_array = vertices;
- dw->gl_ref_normal_array = normals;
- }
- }
-
- /* Marker "reflections" */
- if ( dw->gl_use_buffers ) {
- glGenBuffersARB(1, &dw->gl_marker_vertex_buffer);
- glGenBuffersARB(1, &dw->gl_marker_normal_buffer);
- }
- reflection = ctx->reflectionlist->reflections;
- i = 0;
- while ( reflection != NULL ) {
- if ( reflection->type == REFLECTION_MARKER ) i++;
- reflection = reflection->next;
- };
- dw->gl_marker_num_vertices = i*VERTICES_IN_A_BLOB;
- if ( dw->gl_marker_num_vertices ) {
- i = 0;
- reflection = ctx->reflectionlist->reflections;
- vertices = malloc(3*dw->gl_marker_num_vertices*sizeof(GLfloat));
- normals = malloc(3*dw->gl_marker_num_vertices*sizeof(GLfloat));
- while ( reflection != NULL ) {
- if ( reflection->type == REFLECTION_MARKER ) {
- double size = 0.15;
- DRAW_BLOB
- }
- reflection = reflection->next;
- };
- if ( dw->gl_use_buffers ) {
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_marker_vertex_buffer);
- glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_marker_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
- free(vertices);
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_marker_normal_buffer);
- glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_marker_num_vertices*sizeof(GLfloat), normals, GL_STATIC_DRAW);
- free(normals);
- } else {
- dw->gl_marker_vertex_array = vertices;
- dw->gl_marker_normal_array = normals;
- }
- }
-
- /* Generated reflections */
- if ( dw->gl_use_buffers ) {
- glGenBuffersARB(1, &dw->gl_gen_vertex_buffer);
- glGenBuffersARB(1, &dw->gl_gen_normal_buffer);
- }
- if ( ctx->integrated != NULL ) {
- reflection = ctx->integrated->reflections;
- i = 0;
- while ( reflection != NULL ) {
- if ( reflection->type == REFLECTION_GENERATED ) i++;
- reflection = reflection->next;
- };
- dw->gl_gen_num_vertices = i*VERTICES_IN_A_BLOB;
- if ( dw->gl_gen_num_vertices ) {
- i = 0;
- reflection = ctx->integrated->reflections;
- vertices = malloc(3*dw->gl_gen_num_vertices*sizeof(GLfloat));
- normals = malloc(3*dw->gl_gen_num_vertices*sizeof(GLfloat));
- while ( reflection != NULL ) {
- double size = 5.0 * log(1+0.1*reflection->intensity);
- DRAW_BLOB
- reflection = reflection->next;
- };
- if ( dw->gl_use_buffers ) {
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_gen_vertex_buffer);
- glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_gen_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
- free(vertices);
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_gen_normal_buffer);
- glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_gen_num_vertices*sizeof(GLfloat), normals, GL_STATIC_DRAW);
- free(normals);
- glBindBufferARB(GL_ARRAY_BUFFER, 0); /* ************* */
- } else {
- dw->gl_gen_vertex_array = vertices;
- dw->gl_gen_normal_array = normals;
- }
- }
- } else {
- dw->gl_gen_num_vertices = 0;
- }
-
- /* Indexing lines */
- glLineWidth(2.0);
- if ( ctx->cell && dw->lines ) {
-
- int max_ind;
- signed int h, k, l;
-
- max_ind = 10;
- dw->gl_line_num_vertices = 3*2*((2*1+1)*(2*1+1));
-
- if ( dw->gl_use_buffers ) {
- glGenBuffersARB(1, &dw->gl_line_vertex_buffer);
- }
- reflection = ctx->reflectionlist->reflections;
- vertices = malloc(3*dw->gl_line_num_vertices*sizeof(GLfloat));
-
- i=0;
-
- /* Lines parallel to a */
- for ( k=-1; k<=1; k++ ) {
- for ( l=-1; l<=1; l++ ) {
- vertices[3*i + 0] = (ctx->cell->a.x*(-max_ind) + ctx->cell->b.x*k + ctx->cell->c.x*l)/1e9;
- vertices[3*i + 1] = (ctx->cell->a.y*(-max_ind) + ctx->cell->b.y*k + ctx->cell->c.y*l)/1e9;
- vertices[3*i + 2] = (ctx->cell->a.z*(-max_ind) + ctx->cell->b.z*k + ctx->cell->c.z*l)/1e9;
- i++;
- vertices[3*i + 0] = (ctx->cell->a.x*(max_ind) + ctx->cell->b.x*k + ctx->cell->c.x*l)/1e9;
- vertices[3*i + 1] = (ctx->cell->a.y*(max_ind) + ctx->cell->b.y*k + ctx->cell->c.y*l)/1e9;
- vertices[3*i + 2] = (ctx->cell->a.z*(max_ind) + ctx->cell->b.z*k + ctx->cell->c.z*l)/1e9;
- i++;
- }
- }
- /* Lines parallel to b */
- for ( h=-1; h<=1; h++ ) {
- for ( l=-1; l<=1; l++ ) {
- vertices[3*i + 0] = (ctx->cell->a.x*h + ctx->cell->b.x*(-max_ind) + ctx->cell->c.x*l)/1e9;
- vertices[3*i + 1] = (ctx->cell->a.y*h + ctx->cell->b.y*(-max_ind) + ctx->cell->c.y*l)/1e9;
- vertices[3*i + 2] = (ctx->cell->a.z*h + ctx->cell->b.z*(-max_ind) + ctx->cell->c.z*l)/1e9;
- i++;
- vertices[3*i + 0] = (ctx->cell->a.x*h + ctx->cell->b.x*(max_ind) + ctx->cell->c.x*l)/1e9;
- vertices[3*i + 1] = (ctx->cell->a.y*h + ctx->cell->b.y*(max_ind) + ctx->cell->c.y*l)/1e9;
- vertices[3*i + 2] = (ctx->cell->a.z*h + ctx->cell->b.z*(max_ind) + ctx->cell->c.z*l)/1e9;
- i++;
- }
- }
- /* Lines parallel to c */
- for ( h=-1; h<=1; h++ ) {
- for ( k=-1; k<=1; k++ ) {
- vertices[3*i + 0] = (ctx->cell->a.x*h + ctx->cell->b.x*k + ctx->cell->c.x*(-max_ind))/1e9;
- vertices[3*i + 1] = (ctx->cell->a.y*h + ctx->cell->b.y*k + ctx->cell->c.y*(-max_ind))/1e9;
- vertices[3*i + 2] = (ctx->cell->a.z*h + ctx->cell->b.z*k + ctx->cell->c.z*(-max_ind))/1e9;
- i++;
- vertices[3*i + 0] = (ctx->cell->a.x*h + ctx->cell->b.x*k + ctx->cell->c.x*(max_ind))/1e9;
- vertices[3*i + 1] = (ctx->cell->a.y*h + ctx->cell->b.y*k + ctx->cell->c.y*(max_ind))/1e9;
- vertices[3*i + 2] = (ctx->cell->a.z*h + ctx->cell->b.z*k + ctx->cell->c.z*(max_ind))/1e9;
- i++;
- }
- }
-
- if ( dw->gl_use_buffers ) {
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_line_vertex_buffer);
- glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_line_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
- free(vertices);
- } else {
- dw->gl_line_vertex_array = vertices;
- }
-
- }
-
- dw->gl_list_id = glGenLists(1);
- glNewList(dw->gl_list_id, GL_COMPILE);
-
- #if 0
- GLUquadric *quad;
- quad = gluNewQuadric();
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, yellow);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, yellow);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 10.0);
- gluSphere(quad, 10, 32, 32);
- #endif
-
- /* Bounding cube: 100 nm^-1 side length */
- if ( dw->cube ) {
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, blue);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glBegin(GL_LINE_LOOP);
- glNormal3f(50.0, 50.0, 50.0);
- glVertex3f(50.0, 50.0, 50.0);
- glNormal3f(-50.0, 50.0, 50.0);
- glVertex3f(-50.0, 50.0, 50.0);
- glNormal3f(-50.0, -50.0, 50.0);
- glVertex3f(-50.0, -50.0, 50.0);
- glNormal3f(50.0, -50.0, 50.0);
- glVertex3f(50.0, -50.0, 50.0);
-
- glEnd();
- glBegin(GL_LINE_LOOP);
- glNormal3f(50.0, 50.0, -50.0);
- glVertex3f(50.0, 50.0, -50.0);
- glNormal3f(-50.0, 50.0, -50.0);
- glVertex3f(-50.0, 50.0, -50.0);
- glNormal3f(-50.0, -50.0, -50.0);
- glVertex3f(-50.0, -50.0, -50.0);
- glNormal3f(50.0, -50.0, -50.0);
- glVertex3f(50.0, -50.0, -50.0);
- glEnd();
- glBegin(GL_LINES);
- glNormal3f(50.0, 50.0, 50.0);
- glVertex3f(50.0, 50.0, 50.0);
- glNormal3f(50.0, 50.0, -50.0);
- glVertex3f(50.0, 50.0, -50.0);
- glNormal3f(-50.0, 50.0, 50.0);
- glVertex3f(-50.0, 50.0, 50.0);
- glNormal3f(-50.0, 50.0, -50.0);
- glVertex3f(-50.0, 50.0, -50.0);
- glNormal3f(-50.0, -50.0, 50.0);
- glVertex3f(-50.0, -50.0, 50.0);
- glNormal3f(-50.0, -50.0, -50.0);
- glVertex3f(-50.0, -50.0, -50.0);
- glNormal3f(50.0, -50.0, 50.0);
- glVertex3f(50.0, -50.0, 50.0);
- glNormal3f(50.0, -50.0, -50.0);
- glVertex3f(50.0, -50.0, -50.0);
- glEnd();
- }
-
- /* x, y, z pointers */
- int pointer_head_face;
- glPushMatrix();
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, red);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
- glScalef(10.0, 1.0, 1.0);
- DRAW_POINTER_LINE
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
- DRAW_POINTER_HEAD
- glPopMatrix();
-
- glPushMatrix();
- glRotatef(90.0, 0.0, 0.0, 1.0);
- glScalef(10.0, 1.0, 1.0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, green);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
- DRAW_POINTER_LINE
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green);
- DRAW_POINTER_HEAD
- glPopMatrix();
-
- glPushMatrix();
- glRotatef(-90.0, 0.0, 1.0, 0.0);
- glScalef(10.0, 1.0, 1.0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, bblue);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
- DRAW_POINTER_LINE
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, bblue);
- DRAW_POINTER_HEAD
- glPopMatrix();
-
- /* Plot the other reflections */
- reflection = ctx->reflectionlist->reflections;
- while ( reflection != NULL ) {
-
- if ( reflection->type == REFLECTION_VECTOR_MARKER_1 ) {
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glBegin(GL_LINES);
- glNormal3f(0.0, 0.0, 0.0);
- glVertex3f(0.0, 0.0, 0.0);
- glNormal3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
- glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
- glEnd();
-
- }
-
- if ( reflection->type == REFLECTION_VECTOR_MARKER_2 ) {
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glBegin(GL_LINES);
- glNormal3f(0.0, 0.0, 0.0);
- glVertex3f(0.0, 0.0, 0.0);
- glNormal3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
- glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
- glEnd();
-
- }
-
- if ( reflection->type == REFLECTION_VECTOR_MARKER_3 ) {
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glBegin(GL_LINES);
- glNormal3f(0.0, 0.0, 0.0);
- glVertex3f(0.0, 0.0, 0.0);
- glNormal3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
- glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
- glEnd();
-
- }
-
- reflection = reflection->next;
-
- };
-
- /* Draw the reciprocal unit cell if one is available */
- if ( ctx->cell && !dw->lines ) {
- glBegin(GL_LINE_STRIP);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, red);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glNormal3f(1.0, 0.0, 0.0);
- glVertex3f(0.0, 0.0, 0.0);
- glVertex3f(ctx->cell->a.x/1e9, ctx->cell->a.y/1e9, ctx->cell->a.z/1e9);
- glVertex3f(ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
- ctx->cell->a.y/1e9 + ctx->cell->b.y/1e9,
- ctx->cell->a.z/1e9 + ctx->cell->b.z/1e9);
- glVertex3f(ctx->cell->b.x/1e9, ctx->cell->b.y/1e9, ctx->cell->b.z/1e9);
- glVertex3f(0.0, 0.0, 0.0);
- glVertex3f(ctx->cell->c.x/1e9, ctx->cell->c.y/1e9, ctx->cell->c.z/1e9);
- glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->a.x/1e9,
- ctx->cell->c.y/1e9 + ctx->cell->a.y/1e9,
- ctx->cell->c.z/1e9 + ctx->cell->a.z/1e9);
- glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
- ctx->cell->c.y/1e9 + ctx->cell->a.y/1e9 + ctx->cell->b.y/1e9,
- ctx->cell->c.z/1e9 + ctx->cell->a.z/1e9 + ctx->cell->b.z/1e9);
- glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->b.x/1e9,
- ctx->cell->c.y/1e9 + ctx->cell->b.y/1e9,
- ctx->cell->c.z/1e9 + ctx->cell->b.z/1e9);
- glVertex3f(ctx->cell->c.x/1e9, ctx->cell->c.y/1e9, ctx->cell->c.z/1e9);
-
- glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->b.x/1e9,
- ctx->cell->c.y/1e9 + ctx->cell->b.y/1e9,
- ctx->cell->c.z/1e9 + ctx->cell->b.z/1e9);
- glVertex3f(ctx->cell->b.x/1e9, ctx->cell->b.y/1e9, ctx->cell->b.z/1e9);
- glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->b.x/1e9,
- ctx->cell->c.y/1e9 + ctx->cell->b.y/1e9,
- ctx->cell->c.z/1e9 + ctx->cell->b.z/1e9);
- glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
- ctx->cell->c.y/1e9 + ctx->cell->a.y/1e9 + ctx->cell->b.y/1e9,
- ctx->cell->c.z/1e9 + ctx->cell->a.z/1e9 + ctx->cell->b.z/1e9);
- glVertex3f(ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
- ctx->cell->a.y/1e9 + ctx->cell->b.y/1e9,
- ctx->cell->a.z/1e9 + ctx->cell->b.z/1e9);
- glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
- ctx->cell->c.y/1e9 + ctx->cell->a.y/1e9 + ctx->cell->b.y/1e9,
- ctx->cell->c.z/1e9 + ctx->cell->a.z/1e9 + ctx->cell->b.z/1e9);
- glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->a.x/1e9,
- ctx->cell->c.y/1e9 + ctx->cell->a.y/1e9,
- ctx->cell->c.z/1e9 + ctx->cell->a.z/1e9);
- glVertex3f(ctx->cell->a.x/1e9, ctx->cell->a.y/1e9, ctx->cell->a.z/1e9);
- glEnd();
- }
-
- /* Tilt axis */
- if ( ctx->images ) {
- glPushMatrix();
- /* Images rotate clockwise by omega to put tilt axis at +x,
- * so rotate tilt axis anticlockwise by omega.
- * Since the rotation is about +z, this is already anticlockwise
- * when looking down z. */
- glRotatef(ctx->images->images[0].omega, 0.0, 0.0, 1.0);
- glScalef(50.0, 1.0, 1.0);
- glTranslatef(-0.5, 0.0, 0.0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, yellow);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- DRAW_POINTER_LINE
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, yellow);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- DRAW_POINTER_HEAD
- glPopMatrix();
- }
-
- /* Zero plane (must be drawn last for transparency to work) */
- glBegin(GL_QUADS);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, glass);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glNormal3f(0.0, 0.0, 1.0);
- glVertex3f(50.0, 50.0, 0.0);
- glVertex3f(50.0, -50.0, 0.0);
- glVertex3f(-50.0, -50.0, 0.0);
- glVertex3f(-50.0, 50.0, 0.0);
- glEnd();
-
- glEndList();
-
- //printf("DW: Vertex counts: meas:%i, mark:%i, gen:%i\n", dw->gl_ref_num_vertices, dw->gl_marker_num_vertices, dw->gl_gen_num_vertices);
-
-}
-
-static gint displaywindow_gl_expose(GtkWidget *widget, GdkEventExpose *event, DisplayWindow *dw) {
-
- GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
- GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
- float m[4][4];
- GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
- GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 };
- GLfloat blue[] = { 0.0, 0.0, 0.5, 1.0 };
- GLfloat blue_spec[] = { 0.0, 0.0, 1.0, 1.0 };
- GLfloat gold[] = { 0.5, 0.5, 0.0, 1.0 };
- GLfloat gold_spec[] = { 0.9, 0.9, 0.0, 1.0 };
- GLfloat light0_position[] = { 100.0, 100.0, 100.0, 0.0 };
- GLfloat light0_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
- GLfloat light0_specular[] = { 0.8, 0.8, 0.8, 1.0 };
- GLfloat bg_top[] = { 0.0, 0.2, 0.0, 1.0 };
- GLfloat bg_bot[] = { 0.0, 0.0, 0.0, 1.0 };
- GLfloat grey[] = { 0.6, 0.6, 0.6, 1.0 };
-
- if ( !gdk_gl_drawable_gl_begin(gldrawable, glcontext) ) {
- return 0;
- }
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- if ( dw->background ) {
-
- GLfloat w = dw->drawing_area->allocation.width;
- GLfloat h = dw->drawing_area->allocation.height;
- GLfloat aspect = w/h;
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0, 0.0, -20.0);
- /* Draw the background (this is done before setting up rotations) */
- /* Set up "private" projection matrix */
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(-aspect*3.0, aspect*3.0, -3.0, 3.0, 0.001, 21.0);
- /* Draw background plane */
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, black);
- glMaterialfv(GL_FRONT, GL_SPECULAR, black);
- glMaterialf(GL_FRONT, GL_SHININESS, 0.0);
- glBegin(GL_QUADS);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, bg_bot);
- glVertex3f(-3.0*aspect, -3.0, 0.0);
- glVertex3f(+3.0*aspect, -3.0, 0.0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, bg_top);
- glVertex3f(+3.0*aspect, +3.0, 0.0);
- glVertex3f(-3.0*aspect, +3.0, 0.0);
- glEnd();
- /* Restore the old projection matrix */
- glPopMatrix();
- glClear(GL_DEPTH_BUFFER_BIT); /* Background does not count for depth test purposes */
-
- }
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- /* Set up lighting */
- glEnable(GL_LIGHT0);
- glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
- glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
-
- /* The z component of this makes no difference if the projection is orthographic,
- * but controls zoom when perspective is used */
- glTranslatef(0.0, 0.0, -400.0);
- glTranslatef(dw->x_pos, -dw->y_pos, 400.0-dw->distance);
- build_rotmatrix(m, dw->view_quat);
- glMultMatrixf(&m[0][0]);
-
- if ( dw->mode == DW_MAPPED ) {
-
- /* Draw the "measured" reflections */
- if ( dw->gl_ref_num_vertices ) {
- glPointSize(2.0);
- glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, green);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- if ( dw->gl_use_buffers ) {
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_vertex_buffer);
- glVertexPointer(3, GL_FLOAT, 0, NULL);
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_normal_buffer);
- glNormalPointer(GL_FLOAT, 0, NULL);
- glDrawArrays(GL_POINTS, 0, dw->gl_ref_num_vertices);
- glBindBufferARB(GL_ARRAY_BUFFER, 0);
- } else {
- glVertexPointer(3, GL_FLOAT, 0, dw->gl_ref_vertex_array);
- glNormalPointer(GL_FLOAT, 0, dw->gl_ref_normal_array);
- glDrawArrays(GL_POINTS, 0, dw->gl_ref_num_vertices);
- }
- glDisableClientState(GL_NORMAL_ARRAY);
- glPopClientAttrib();
- }
-
- /* Draw marker points */
- if ( dw->gl_marker_num_vertices ) {
- glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blue_spec);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0);
- if ( dw->gl_use_buffers ) {
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_marker_vertex_buffer);
- glVertexPointer(3, GL_FLOAT, 0, NULL);
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_marker_normal_buffer);
- glNormalPointer(GL_FLOAT, 0, NULL);
- glDrawArrays(GL_QUADS, 0, dw->gl_marker_num_vertices);
- glBindBufferARB(GL_ARRAY_BUFFER, 0);
- } else {
- glVertexPointer(3, GL_FLOAT, 0, dw->gl_marker_vertex_array);
- glNormalPointer(GL_FLOAT, 0, dw->gl_marker_normal_array);
- glDrawArrays(GL_QUADS, 0, dw->gl_marker_num_vertices);
- }
- glDisableClientState(GL_NORMAL_ARRAY);
- glPopClientAttrib();
- }
-
- } else {
-
- /* Draw generated reflections */
- if ( dw->gl_gen_num_vertices ) {
- glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, gold);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gold_spec);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.0);
- if ( dw->gl_use_buffers ) {
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_gen_vertex_buffer);
- glVertexPointer(3, GL_FLOAT, 0, NULL);
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_gen_normal_buffer);
- glNormalPointer(GL_FLOAT, 0, NULL);
- glDrawArrays(GL_QUADS, 0, dw->gl_gen_num_vertices);
- glBindBufferARB(GL_ARRAY_BUFFER, 0);
- } else {
- glVertexPointer(3, GL_FLOAT, 0, dw->gl_gen_vertex_array);
- glNormalPointer(GL_FLOAT, 0, dw->gl_gen_normal_array);
- glDrawArrays(GL_QUADS, 0, dw->gl_gen_num_vertices);
- }
- glDisableClientState(GL_NORMAL_ARRAY);
- glPopClientAttrib();
- }
-
- }
-
- /* Draw indexing lines */
- if ( dw->lines && dw->gl_line_num_vertices ) {
- glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
- glEnableClientState(GL_VERTEX_ARRAY);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, grey);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- if ( dw->gl_use_buffers ) {
- glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_line_vertex_buffer);
- glVertexPointer(3, GL_FLOAT, 0, NULL);
- glDrawArrays(GL_LINES, 0, dw->gl_line_num_vertices);
- glBindBufferARB(GL_ARRAY_BUFFER, 0);
- } else {
- glVertexPointer(3, GL_FLOAT, 0, dw->gl_line_vertex_array);
- glDrawArrays(GL_LINES, 0, dw->gl_line_num_vertices);
- }
- glPopClientAttrib();
- }
-
- /* Draw everything else */
- glCallList(dw->gl_list_id);
-
- if ( gdk_gl_drawable_is_double_buffered(gldrawable) ) {
- gdk_gl_drawable_swap_buffers(gldrawable);
- } else {
- glFlush();
- }
-
- gdk_gl_drawable_gl_end(gldrawable);
-
- return TRUE;
-
-}
-
static gint displaywindow_gl_realise(GtkWidget *widget, DisplayWindow *dw) {
GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
@@ -849,8 +122,8 @@ static gint displaywindow_gl_realise(GtkWidget *widget, DisplayWindow *dw) {
return 0;
}
- displaywindow_gl_set_ortho(dw, w, h);
- displaywindow_gl_prepare(dw);
+ glbits_set_ortho(dw, w, h);
+ glbits_prepare(dw);
gdk_gl_drawable_gl_end(gldrawable);
@@ -858,64 +131,8 @@ static gint displaywindow_gl_realise(GtkWidget *widget, DisplayWindow *dw) {
}
-static gboolean displaywindow_gl_configure(GtkWidget *widget, GdkEventConfigure *event, DisplayWindow *dw) {
-
- GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
- GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
- GLfloat w = widget->allocation.width;
- GLfloat h = widget->allocation.height;
-
- /* Set viewport */
- if ( !gdk_gl_drawable_gl_begin(gldrawable, glcontext) ) {
- return FALSE;
- }
- glViewport(0, 0, w, h);
-
- glEnable(GL_LIGHTING);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glShadeModel(GL_SMOOTH);
- glEnable(GL_LINE_SMOOTH);
-
- /* Nudge the projection matrix routines to preserve the aspect ratio */
- if ( dw->view == DW_ORTHO ) {
- displaywindow_gl_set_ortho(dw, w, h);
- } else {
- displaywindow_gl_set_perspective(dw, w, h);
- }
-
- gdk_gl_drawable_gl_end(gldrawable);
-
- return FALSE;
-
-}
-
-static void displaywindow_gl_free_resources(DisplayWindow *dw) {
-
- if ( dw->gl_use_buffers ) {
- glDeleteBuffersARB(1, &dw->gl_ref_vertex_buffer);
- glDeleteBuffersARB(1, &dw->gl_ref_normal_buffer);
- glDeleteBuffersARB(1, &dw->gl_marker_vertex_buffer);
- glDeleteBuffersARB(1, &dw->gl_marker_normal_buffer);
- glDeleteBuffersARB(1, &dw->gl_gen_vertex_buffer);
- glDeleteBuffersARB(1, &dw->gl_gen_normal_buffer);
- glDeleteBuffersARB(1, &dw->gl_line_vertex_buffer);
- } else {
- free(dw->gl_ref_vertex_array);
- free(dw->gl_ref_normal_array);
- free(dw->gl_marker_vertex_array);
- free(dw->gl_marker_normal_array);
- free(dw->gl_gen_vertex_array);
- free(dw->gl_gen_normal_array);
- free(dw->gl_line_vertex_array);
- }
- glDeleteLists(dw->gl_list_id, 1);
-
-}
-
static gint displaywindow_closedown(GtkWidget *widget, DisplayWindow *dw) {
- displaywindow_gl_free_resources(dw);
+ glbits_free_resources(dw);
gtk_exit(0);
return 0;
}
@@ -1394,9 +611,9 @@ DisplayWindow *displaywindow_open(ControlContext *ctx) {
gtk_widget_set_gl_capability(dw->drawing_area, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dw->drawing_area, gtk_label_new("Reconstruction"));
gtk_widget_add_events(dw->drawing_area, GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_VISIBILITY_NOTIFY_MASK);
- g_signal_connect(GTK_OBJECT(dw->drawing_area), "configure_event", G_CALLBACK(displaywindow_gl_configure), dw);
+ g_signal_connect(GTK_OBJECT(dw->drawing_area), "configure_event", G_CALLBACK(glbits_configure), dw);
g_signal_connect(GTK_OBJECT(dw->drawing_area), "realize", G_CALLBACK(displaywindow_gl_realise), dw);
- g_signal_connect(GTK_OBJECT(dw->drawing_area), "expose_event", G_CALLBACK(displaywindow_gl_expose), dw);
+ g_signal_connect(GTK_OBJECT(dw->drawing_area), "expose_event", G_CALLBACK(glbits_expose), dw);
g_signal_connect(GTK_OBJECT(dw->drawing_area), "button_press_event", G_CALLBACK(displaywindow_gl_button_press), dw);
g_signal_connect(GTK_OBJECT(dw->drawing_area), "motion_notify_event", G_CALLBACK(displaywindow_gl_motion_notify), dw);
@@ -1417,8 +634,8 @@ DisplayWindow *displaywindow_open(ControlContext *ctx) {
}
void displaywindow_update(DisplayWindow *dw) {
- displaywindow_gl_free_resources(dw);
- displaywindow_gl_prepare(dw);
+ glbits_free_resources(dw);
+ glbits_prepare(dw);
gdk_window_invalidate_rect(dw->drawing_area->window, &dw->drawing_area->allocation, FALSE);
}
diff --git a/src/glbits.c b/src/glbits.c
new file mode 100644
index 0000000..194a919
--- /dev/null
+++ b/src/glbits.c
@@ -0,0 +1,814 @@
+/*
+ * glbits.c
+ *
+ * OpenGL bits
+ *
+ * (c) 2007 Thomas White <taw27@cam.ac.uk>
+ *
+ * dtr - Diffraction Tomography Reconstruction
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gdk/gdkgl.h>
+#include <gtk/gtkgl.h>
+#define GL_GLEXT_PROTOTYPES 1
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include <GL/glu.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "displaywindow.h"
+#include "trackball.h"
+#include "reflections.h"
+#include "image.h"
+
+#define BLOB_BITS 5
+#define VERTICES_IN_A_BLOB 4*BLOB_BITS*BLOB_BITS*2
+#define ADD_VERTEX \
+ vertices[3*i + 0] = reflection->x/1e9 + size*xv; \
+ vertices[3*i + 1] = reflection->y/1e9 + size*yv; \
+ vertices[3*i + 2] = reflection->z/1e9 + size*zv; \
+ normals[3*i + 0] = xv; \
+ normals[3*i + 1] = yv; \
+ normals[3*i + 2] = zv; \
+ i++;
+
+#define DRAW_BLOB \
+ double step = M_PI/(double)BLOB_BITS; \
+ int is, js; \
+ for ( is=0; is<BLOB_BITS; is++ ) { \
+ for ( js=0; js<BLOB_BITS*2; js++ ) { \
+ double theta, phi; \
+ GLfloat xv, yv, zv; \
+ theta = (M_PI/(double)BLOB_BITS) * (double)js; \
+ phi = (M_PI/(double)BLOB_BITS) * (double)is; \
+ xv = sin(theta)*sin(phi); \
+ yv = cos(phi); \
+ zv = cos(theta)*sin(phi); \
+ ADD_VERTEX \
+ xv = sin(theta)*sin(phi+step); \
+ yv = cos(phi+step); \
+ zv = cos(theta)*sin(phi+step); \
+ ADD_VERTEX \
+ xv = sin(theta+step)*sin(phi+step); \
+ yv = cos(phi+step); \
+ zv = cos(theta+step)*sin(phi+step); \
+ ADD_VERTEX \
+ xv = sin(theta+step)*sin(phi); \
+ yv = cos(phi); \
+ zv = cos(theta+step)*sin(phi); \
+ ADD_VERTEX \
+ } \
+ }
+
+#define DRAW_POINTER_LINE \
+ glBegin(GL_LINES); \
+ glVertex3f(1.0, 0.0, 0.0); \
+ glVertex3f(0.0, 0.0, 0.0); \
+ glEnd();
+
+#define DRAW_POINTER_HEAD \
+ glPushMatrix(); \
+ for ( pointer_head_face = 1; pointer_head_face <= 4; pointer_head_face++ ) { \
+ glRotatef(90.0, 1.0, 0.0, 0.0); \
+ glBegin(GL_TRIANGLES); \
+ /* One face */ \
+ glNormal3f(0.2, 0.8, 0.0); \
+ glVertex3f(1.0, 0.0, 0.0); \
+ glVertex3f(0.8, 0.2, 0.2); \
+ glVertex3f(0.8, 0.2, -0.2); \
+ /* One quarter of the "bottom square" */ \
+ glNormal3f(1.0, 0.0, 0.0); \
+ glVertex3f(0.8, 0.2, 0.2); \
+ glVertex3f(0.8, 0.2, -0.2); \
+ glVertex3f(0.8, 0.0, 0.0); \
+ glEnd(); \
+ } \
+ glPopMatrix();
+
+void glbits_prepare(DisplayWindow *dw) {
+
+ GLfloat bblue[] = { 0.0, 0.0, 1.0, 1.0 };
+ GLfloat blue[] = { 0.0, 0.0, 0.5, 1.0 };
+ GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };
+ GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 };
+ GLfloat yellow[] = { 1.0, 1.0, 0.0, 1.0 };
+ GLfloat glass[] = { 0.2, 0.0, 0.8, 000.1 };
+ GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
+ Reflection *reflection;
+ int i;
+ ControlContext *ctx;
+ GLfloat *vertices;
+ GLfloat *normals;
+
+ ctx = dw->ctx;
+
+ /* "Measured" reflections */
+ if ( dw->gl_use_buffers ) {
+ glGenBuffersARB(1, &dw->gl_ref_vertex_buffer);
+ glGenBuffersARB(1, &dw->gl_ref_normal_buffer);
+ }
+ reflection = ctx->reflectionlist->reflections;
+ i = 0;
+ while ( reflection != NULL ) {
+ if ( reflection->type == REFLECTION_NORMAL ) i++;
+ reflection = reflection->next;
+ };
+ dw->gl_ref_num_vertices = i;
+ if ( dw->gl_ref_num_vertices ) {
+ i = 0;
+ reflection = ctx->reflectionlist->reflections;
+ vertices = malloc(3*dw->gl_ref_num_vertices*sizeof(GLfloat));
+ normals = malloc(3*dw->gl_ref_num_vertices*sizeof(GLfloat));
+ while ( reflection != NULL ) {
+ if ( reflection->type == REFLECTION_NORMAL ) {
+ vertices[3*i + 0] = reflection->x/1e9;
+ vertices[3*i + 1] = reflection->y/1e9;
+ vertices[3*i + 2] = reflection->z/1e9;
+ normals[3*i + 0] = reflection->x/1e9;
+ normals[3*i + 1] = reflection->y/1e9;
+ normals[3*i + 2] = reflection->z/1e9;
+ i++;
+ }
+ reflection = reflection->next;
+ };
+ if ( dw->gl_use_buffers ) {
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_vertex_buffer);
+ glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_ref_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
+ free(vertices);
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_normal_buffer);
+ glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_ref_num_vertices*sizeof(GLfloat), normals, GL_STATIC_DRAW);
+ free(normals);
+ } else {
+ dw->gl_ref_vertex_array = vertices;
+ dw->gl_ref_normal_array = normals;
+ }
+ }
+
+ /* Marker "reflections" */
+ if ( dw->gl_use_buffers ) {
+ glGenBuffersARB(1, &dw->gl_marker_vertex_buffer);
+ glGenBuffersARB(1, &dw->gl_marker_normal_buffer);
+ }
+ reflection = ctx->reflectionlist->reflections;
+ i = 0;
+ while ( reflection != NULL ) {
+ if ( reflection->type == REFLECTION_MARKER ) i++;
+ reflection = reflection->next;
+ };
+ dw->gl_marker_num_vertices = i*VERTICES_IN_A_BLOB;
+ if ( dw->gl_marker_num_vertices ) {
+ i = 0;
+ reflection = ctx->reflectionlist->reflections;
+ vertices = malloc(3*dw->gl_marker_num_vertices*sizeof(GLfloat));
+ normals = malloc(3*dw->gl_marker_num_vertices*sizeof(GLfloat));
+ while ( reflection != NULL ) {
+ if ( reflection->type == REFLECTION_MARKER ) {
+ double size = 0.15;
+ DRAW_BLOB
+ }
+ reflection = reflection->next;
+ };
+ if ( dw->gl_use_buffers ) {
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_marker_vertex_buffer);
+ glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_marker_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
+ free(vertices);
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_marker_normal_buffer);
+ glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_marker_num_vertices*sizeof(GLfloat), normals, GL_STATIC_DRAW);
+ free(normals);
+ } else {
+ dw->gl_marker_vertex_array = vertices;
+ dw->gl_marker_normal_array = normals;
+ }
+ }
+
+ /* Generated reflections */
+ if ( dw->gl_use_buffers ) {
+ glGenBuffersARB(1, &dw->gl_gen_vertex_buffer);
+ glGenBuffersARB(1, &dw->gl_gen_normal_buffer);
+ }
+ if ( ctx->integrated != NULL ) {
+ reflection = ctx->integrated->reflections;
+ i = 0;
+ while ( reflection != NULL ) {
+ if ( reflection->type == REFLECTION_GENERATED ) i++;
+ reflection = reflection->next;
+ };
+ dw->gl_gen_num_vertices = i*VERTICES_IN_A_BLOB;
+ if ( dw->gl_gen_num_vertices ) {
+ i = 0;
+ reflection = ctx->integrated->reflections;
+ vertices = malloc(3*dw->gl_gen_num_vertices*sizeof(GLfloat));
+ normals = malloc(3*dw->gl_gen_num_vertices*sizeof(GLfloat));
+ while ( reflection != NULL ) {
+ double size = 5.0 * log(1+0.1*reflection->intensity);
+ DRAW_BLOB
+ reflection = reflection->next;
+ };
+ if ( dw->gl_use_buffers ) {
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_gen_vertex_buffer);
+ glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_gen_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
+ free(vertices);
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_gen_normal_buffer);
+ glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_gen_num_vertices*sizeof(GLfloat), normals, GL_STATIC_DRAW);
+ free(normals);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0); /* ************* */
+ } else {
+ dw->gl_gen_vertex_array = vertices;
+ dw->gl_gen_normal_array = normals;
+ }
+ }
+ } else {
+ dw->gl_gen_num_vertices = 0;
+ }
+
+ /* Indexing lines */
+ glLineWidth(2.0);
+ if ( ctx->cell && dw->lines ) {
+
+ int max_ind;
+ signed int h, k, l;
+
+ max_ind = 10;
+ dw->gl_line_num_vertices = 3*2*((2*1+1)*(2*1+1));
+
+ if ( dw->gl_use_buffers ) {
+ glGenBuffersARB(1, &dw->gl_line_vertex_buffer);
+ }
+ reflection = ctx->reflectionlist->reflections;
+ vertices = malloc(3*dw->gl_line_num_vertices*sizeof(GLfloat));
+
+ i=0;
+
+ /* Lines parallel to a */
+ for ( k=-1; k<=1; k++ ) {
+ for ( l=-1; l<=1; l++ ) {
+ vertices[3*i + 0] = (ctx->cell->a.x*(-max_ind) + ctx->cell->b.x*k + ctx->cell->c.x*l)/1e9;
+ vertices[3*i + 1] = (ctx->cell->a.y*(-max_ind) + ctx->cell->b.y*k + ctx->cell->c.y*l)/1e9;
+ vertices[3*i + 2] = (ctx->cell->a.z*(-max_ind) + ctx->cell->b.z*k + ctx->cell->c.z*l)/1e9;
+ i++;
+ vertices[3*i + 0] = (ctx->cell->a.x*(max_ind) + ctx->cell->b.x*k + ctx->cell->c.x*l)/1e9;
+ vertices[3*i + 1] = (ctx->cell->a.y*(max_ind) + ctx->cell->b.y*k + ctx->cell->c.y*l)/1e9;
+ vertices[3*i + 2] = (ctx->cell->a.z*(max_ind) + ctx->cell->b.z*k + ctx->cell->c.z*l)/1e9;
+ i++;
+ }
+ }
+ /* Lines parallel to b */
+ for ( h=-1; h<=1; h++ ) {
+ for ( l=-1; l<=1; l++ ) {
+ vertices[3*i + 0] = (ctx->cell->a.x*h + ctx->cell->b.x*(-max_ind) + ctx->cell->c.x*l)/1e9;
+ vertices[3*i + 1] = (ctx->cell->a.y*h + ctx->cell->b.y*(-max_ind) + ctx->cell->c.y*l)/1e9;
+ vertices[3*i + 2] = (ctx->cell->a.z*h + ctx->cell->b.z*(-max_ind) + ctx->cell->c.z*l)/1e9;
+ i++;
+ vertices[3*i + 0] = (ctx->cell->a.x*h + ctx->cell->b.x*(max_ind) + ctx->cell->c.x*l)/1e9;
+ vertices[3*i + 1] = (ctx->cell->a.y*h + ctx->cell->b.y*(max_ind) + ctx->cell->c.y*l)/1e9;
+ vertices[3*i + 2] = (ctx->cell->a.z*h + ctx->cell->b.z*(max_ind) + ctx->cell->c.z*l)/1e9;
+ i++;
+ }
+ }
+ /* Lines parallel to c */
+ for ( h=-1; h<=1; h++ ) {
+ for ( k=-1; k<=1; k++ ) {
+ vertices[3*i + 0] = (ctx->cell->a.x*h + ctx->cell->b.x*k + ctx->cell->c.x*(-max_ind))/1e9;
+ vertices[3*i + 1] = (ctx->cell->a.y*h + ctx->cell->b.y*k + ctx->cell->c.y*(-max_ind))/1e9;
+ vertices[3*i + 2] = (ctx->cell->a.z*h + ctx->cell->b.z*k + ctx->cell->c.z*(-max_ind))/1e9;
+ i++;
+ vertices[3*i + 0] = (ctx->cell->a.x*h + ctx->cell->b.x*k + ctx->cell->c.x*(max_ind))/1e9;
+ vertices[3*i + 1] = (ctx->cell->a.y*h + ctx->cell->b.y*k + ctx->cell->c.y*(max_ind))/1e9;
+ vertices[3*i + 2] = (ctx->cell->a.z*h + ctx->cell->b.z*k + ctx->cell->c.z*(max_ind))/1e9;
+ i++;
+ }
+ }
+
+ if ( dw->gl_use_buffers ) {
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_line_vertex_buffer);
+ glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_line_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
+ free(vertices);
+ } else {
+ dw->gl_line_vertex_array = vertices;
+ }
+
+ }
+
+ dw->gl_list_id = glGenLists(1);
+ glNewList(dw->gl_list_id, GL_COMPILE);
+
+ #if 0
+ GLUquadric *quad;
+ quad = gluNewQuadric();
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, yellow);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, yellow);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 10.0);
+ gluSphere(quad, 10, 32, 32);
+ #endif
+
+ /* Bounding cube: 100 nm^-1 side length */
+ if ( dw->cube ) {
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, blue);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glBegin(GL_LINE_LOOP);
+ glNormal3f(50.0, 50.0, 50.0);
+ glVertex3f(50.0, 50.0, 50.0);
+ glNormal3f(-50.0, 50.0, 50.0);
+ glVertex3f(-50.0, 50.0, 50.0);
+ glNormal3f(-50.0, -50.0, 50.0);
+ glVertex3f(-50.0, -50.0, 50.0);
+ glNormal3f(50.0, -50.0, 50.0);
+ glVertex3f(50.0, -50.0, 50.0);
+
+ glEnd();
+ glBegin(GL_LINE_LOOP);
+ glNormal3f(50.0, 50.0, -50.0);
+ glVertex3f(50.0, 50.0, -50.0);
+ glNormal3f(-50.0, 50.0, -50.0);
+ glVertex3f(-50.0, 50.0, -50.0);
+ glNormal3f(-50.0, -50.0, -50.0);
+ glVertex3f(-50.0, -50.0, -50.0);
+ glNormal3f(50.0, -50.0, -50.0);
+ glVertex3f(50.0, -50.0, -50.0);
+ glEnd();
+ glBegin(GL_LINES);
+ glNormal3f(50.0, 50.0, 50.0);
+ glVertex3f(50.0, 50.0, 50.0);
+ glNormal3f(50.0, 50.0, -50.0);
+ glVertex3f(50.0, 50.0, -50.0);
+ glNormal3f(-50.0, 50.0, 50.0);
+ glVertex3f(-50.0, 50.0, 50.0);
+ glNormal3f(-50.0, 50.0, -50.0);
+ glVertex3f(-50.0, 50.0, -50.0);
+ glNormal3f(-50.0, -50.0, 50.0);
+ glVertex3f(-50.0, -50.0, 50.0);
+ glNormal3f(-50.0, -50.0, -50.0);
+ glVertex3f(-50.0, -50.0, -50.0);
+ glNormal3f(50.0, -50.0, 50.0);
+ glVertex3f(50.0, -50.0, 50.0);
+ glNormal3f(50.0, -50.0, -50.0);
+ glVertex3f(50.0, -50.0, -50.0);
+ glEnd();
+ }
+
+ /* x, y, z pointers */
+ int pointer_head_face;
+ glPushMatrix();
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, red);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
+ glScalef(10.0, 1.0, 1.0);
+ DRAW_POINTER_LINE
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
+ DRAW_POINTER_HEAD
+ glPopMatrix();
+
+ glPushMatrix();
+ glRotatef(90.0, 0.0, 0.0, 1.0);
+ glScalef(10.0, 1.0, 1.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, green);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
+ DRAW_POINTER_LINE
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green);
+ DRAW_POINTER_HEAD
+ glPopMatrix();
+
+ glPushMatrix();
+ glRotatef(-90.0, 0.0, 1.0, 0.0);
+ glScalef(10.0, 1.0, 1.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, bblue);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
+ DRAW_POINTER_LINE
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, bblue);
+ DRAW_POINTER_HEAD
+ glPopMatrix();
+
+ /* Plot the other reflections */
+ reflection = ctx->reflectionlist->reflections;
+ while ( reflection != NULL ) {
+
+ if ( reflection->type == REFLECTION_VECTOR_MARKER_1 ) {
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glBegin(GL_LINES);
+ glNormal3f(0.0, 0.0, 0.0);
+ glVertex3f(0.0, 0.0, 0.0);
+ glNormal3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glEnd();
+
+ }
+
+ if ( reflection->type == REFLECTION_VECTOR_MARKER_2 ) {
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glBegin(GL_LINES);
+ glNormal3f(0.0, 0.0, 0.0);
+ glVertex3f(0.0, 0.0, 0.0);
+ glNormal3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glEnd();
+
+ }
+
+ if ( reflection->type == REFLECTION_VECTOR_MARKER_3 ) {
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glBegin(GL_LINES);
+ glNormal3f(0.0, 0.0, 0.0);
+ glVertex3f(0.0, 0.0, 0.0);
+ glNormal3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glEnd();
+
+ }
+
+ reflection = reflection->next;
+
+ };
+
+ /* Draw the reciprocal unit cell if one is available */
+ if ( ctx->cell && !dw->lines ) {
+ glBegin(GL_LINE_STRIP);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, red);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glNormal3f(1.0, 0.0, 0.0);
+ glVertex3f(0.0, 0.0, 0.0);
+ glVertex3f(ctx->cell->a.x/1e9, ctx->cell->a.y/1e9, ctx->cell->a.z/1e9);
+ glVertex3f(ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
+ ctx->cell->a.y/1e9 + ctx->cell->b.y/1e9,
+ ctx->cell->a.z/1e9 + ctx->cell->b.z/1e9);
+ glVertex3f(ctx->cell->b.x/1e9, ctx->cell->b.y/1e9, ctx->cell->b.z/1e9);
+ glVertex3f(0.0, 0.0, 0.0);
+ glVertex3f(ctx->cell->c.x/1e9, ctx->cell->c.y/1e9, ctx->cell->c.z/1e9);
+ glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->a.x/1e9,
+ ctx->cell->c.y/1e9 + ctx->cell->a.y/1e9,
+ ctx->cell->c.z/1e9 + ctx->cell->a.z/1e9);
+ glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
+ ctx->cell->c.y/1e9 + ctx->cell->a.y/1e9 + ctx->cell->b.y/1e9,
+ ctx->cell->c.z/1e9 + ctx->cell->a.z/1e9 + ctx->cell->b.z/1e9);
+ glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->b.x/1e9,
+ ctx->cell->c.y/1e9 + ctx->cell->b.y/1e9,
+ ctx->cell->c.z/1e9 + ctx->cell->b.z/1e9);
+ glVertex3f(ctx->cell->c.x/1e9, ctx->cell->c.y/1e9, ctx->cell->c.z/1e9);
+
+ glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->b.x/1e9,
+ ctx->cell->c.y/1e9 + ctx->cell->b.y/1e9,
+ ctx->cell->c.z/1e9 + ctx->cell->b.z/1e9);
+ glVertex3f(ctx->cell->b.x/1e9, ctx->cell->b.y/1e9, ctx->cell->b.z/1e9);
+ glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->b.x/1e9,
+ ctx->cell->c.y/1e9 + ctx->cell->b.y/1e9,
+ ctx->cell->c.z/1e9 + ctx->cell->b.z/1e9);
+ glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
+ ctx->cell->c.y/1e9 + ctx->cell->a.y/1e9 + ctx->cell->b.y/1e9,
+ ctx->cell->c.z/1e9 + ctx->cell->a.z/1e9 + ctx->cell->b.z/1e9);
+ glVertex3f(ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
+ ctx->cell->a.y/1e9 + ctx->cell->b.y/1e9,
+ ctx->cell->a.z/1e9 + ctx->cell->b.z/1e9);
+ glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
+ ctx->cell->c.y/1e9 + ctx->cell->a.y/1e9 + ctx->cell->b.y/1e9,
+ ctx->cell->c.z/1e9 + ctx->cell->a.z/1e9 + ctx->cell->b.z/1e9);
+ glVertex3f(ctx->cell->c.x/1e9 + ctx->cell->a.x/1e9,
+ ctx->cell->c.y/1e9 + ctx->cell->a.y/1e9,
+ ctx->cell->c.z/1e9 + ctx->cell->a.z/1e9);
+ glVertex3f(ctx->cell->a.x/1e9, ctx->cell->a.y/1e9, ctx->cell->a.z/1e9);
+ glEnd();
+ }
+
+ /* Tilt axis */
+ if ( ctx->images ) {
+ glPushMatrix();
+ /* Images rotate clockwise by omega to put tilt axis at +x,
+ * so rotate tilt axis anticlockwise by omega.
+ * Since the rotation is about +z, this is already anticlockwise
+ * when looking down z. */
+ glRotatef(ctx->images->images[0].omega, 0.0, 0.0, 1.0);
+ glScalef(50.0, 1.0, 1.0);
+ glTranslatef(-0.5, 0.0, 0.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, yellow);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ DRAW_POINTER_LINE
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, yellow);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ DRAW_POINTER_HEAD
+ glPopMatrix();
+ }
+
+ /* Zero plane (must be drawn last for transparency to work) */
+ glBegin(GL_QUADS);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, glass);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glNormal3f(0.0, 0.0, 1.0);
+ glVertex3f(50.0, 50.0, 0.0);
+ glVertex3f(50.0, -50.0, 0.0);
+ glVertex3f(-50.0, -50.0, 0.0);
+ glVertex3f(-50.0, 50.0, 0.0);
+ glEnd();
+
+ glEndList();
+
+ //printf("DW: Vertex counts: meas:%i, mark:%i, gen:%i\n", dw->gl_ref_num_vertices, dw->gl_marker_num_vertices, dw->gl_gen_num_vertices);
+
+}
+
+void glbits_set_ortho(DisplayWindow *dw, GLfloat w, GLfloat h) {
+
+ GLfloat aspect = w/h;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-aspect*(dw->distance/2.0), aspect*(dw->distance/2.0), -(dw->distance/2.0), (dw->distance/2.0), 0.001, 400.0);
+ glMatrixMode(GL_MODELVIEW);
+
+}
+
+void glbits_set_perspective(DisplayWindow *dw, GLfloat w, GLfloat h) {
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(50.0, w/h, 0.001, 400.0);
+ glMatrixMode(GL_MODELVIEW);
+
+}
+
+gint glbits_expose(GtkWidget *widget, GdkEventExpose *event, DisplayWindow *dw) {
+
+ GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
+ GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
+ float m[4][4];
+ GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
+ GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 };
+ GLfloat blue[] = { 0.0, 0.0, 0.5, 1.0 };
+ GLfloat blue_spec[] = { 0.0, 0.0, 1.0, 1.0 };
+ GLfloat gold[] = { 0.5, 0.5, 0.0, 1.0 };
+ GLfloat gold_spec[] = { 0.9, 0.9, 0.0, 1.0 };
+ GLfloat light0_position[] = { 100.0, 100.0, 100.0, 0.0 };
+ GLfloat light0_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
+ GLfloat light0_specular[] = { 0.8, 0.8, 0.8, 1.0 };
+ GLfloat bg_top[] = { 0.0, 0.2, 0.0, 1.0 };
+ GLfloat bg_bot[] = { 0.0, 0.0, 0.0, 1.0 };
+ GLfloat grey[] = { 0.6, 0.6, 0.6, 1.0 };
+
+ if ( !gdk_gl_drawable_gl_begin(gldrawable, glcontext) ) {
+ return 0;
+ }
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if ( dw->background ) {
+
+ GLfloat w = dw->drawing_area->allocation.width;
+ GLfloat h = dw->drawing_area->allocation.height;
+ GLfloat aspect = w/h;
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -20.0);
+ /* Draw the background (this is done before setting up rotations) */
+ /* Set up "private" projection matrix */
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(-aspect*3.0, aspect*3.0, -3.0, 3.0, 0.001, 21.0);
+ /* Draw background plane */
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, black);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT, GL_SHININESS, 0.0);
+ glBegin(GL_QUADS);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, bg_bot);
+ glVertex3f(-3.0*aspect, -3.0, 0.0);
+ glVertex3f(+3.0*aspect, -3.0, 0.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, bg_top);
+ glVertex3f(+3.0*aspect, +3.0, 0.0);
+ glVertex3f(-3.0*aspect, +3.0, 0.0);
+ glEnd();
+ /* Restore the old projection matrix */
+ glPopMatrix();
+ glClear(GL_DEPTH_BUFFER_BIT); /* Background does not count for depth test purposes */
+
+ }
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ /* Set up lighting */
+ glEnable(GL_LIGHT0);
+ glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
+
+ /* The z component of this makes no difference if the projection is orthographic,
+ * but controls zoom when perspective is used */
+ glTranslatef(0.0, 0.0, -400.0);
+ glTranslatef(dw->x_pos, -dw->y_pos, 400.0-dw->distance);
+ build_rotmatrix(m, dw->view_quat);
+ glMultMatrixf(&m[0][0]);
+
+ if ( dw->mode == DW_MAPPED ) {
+
+ /* Draw the "measured" reflections */
+ if ( dw->gl_ref_num_vertices ) {
+ glPointSize(2.0);
+ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, green);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ if ( dw->gl_use_buffers ) {
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_vertex_buffer);
+ glVertexPointer(3, GL_FLOAT, 0, NULL);
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_normal_buffer);
+ glNormalPointer(GL_FLOAT, 0, NULL);
+ glDrawArrays(GL_POINTS, 0, dw->gl_ref_num_vertices);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ } else {
+ glVertexPointer(3, GL_FLOAT, 0, dw->gl_ref_vertex_array);
+ glNormalPointer(GL_FLOAT, 0, dw->gl_ref_normal_array);
+ glDrawArrays(GL_POINTS, 0, dw->gl_ref_num_vertices);
+ }
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glPopClientAttrib();
+ }
+
+ /* Draw marker points */
+ if ( dw->gl_marker_num_vertices ) {
+ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blue_spec);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0);
+ if ( dw->gl_use_buffers ) {
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_marker_vertex_buffer);
+ glVertexPointer(3, GL_FLOAT, 0, NULL);
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_marker_normal_buffer);
+ glNormalPointer(GL_FLOAT, 0, NULL);
+ glDrawArrays(GL_QUADS, 0, dw->gl_marker_num_vertices);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ } else {
+ glVertexPointer(3, GL_FLOAT, 0, dw->gl_marker_vertex_array);
+ glNormalPointer(GL_FLOAT, 0, dw->gl_marker_normal_array);
+ glDrawArrays(GL_QUADS, 0, dw->gl_marker_num_vertices);
+ }
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glPopClientAttrib();
+ }
+
+ } else {
+
+ /* Draw generated reflections */
+ if ( dw->gl_gen_num_vertices ) {
+ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, gold);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gold_spec);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.0);
+ if ( dw->gl_use_buffers ) {
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_gen_vertex_buffer);
+ glVertexPointer(3, GL_FLOAT, 0, NULL);
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_gen_normal_buffer);
+ glNormalPointer(GL_FLOAT, 0, NULL);
+ glDrawArrays(GL_QUADS, 0, dw->gl_gen_num_vertices);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ } else {
+ glVertexPointer(3, GL_FLOAT, 0, dw->gl_gen_vertex_array);
+ glNormalPointer(GL_FLOAT, 0, dw->gl_gen_normal_array);
+ glDrawArrays(GL_QUADS, 0, dw->gl_gen_num_vertices);
+ }
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glPopClientAttrib();
+ }
+
+ }
+
+ /* Draw indexing lines */
+ if ( dw->lines && dw->gl_line_num_vertices ) {
+ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, grey);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ if ( dw->gl_use_buffers ) {
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_line_vertex_buffer);
+ glVertexPointer(3, GL_FLOAT, 0, NULL);
+ glDrawArrays(GL_LINES, 0, dw->gl_line_num_vertices);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ } else {
+ glVertexPointer(3, GL_FLOAT, 0, dw->gl_line_vertex_array);
+ glDrawArrays(GL_LINES, 0, dw->gl_line_num_vertices);
+ }
+ glPopClientAttrib();
+ }
+
+ /* Draw everything else */
+ glCallList(dw->gl_list_id);
+
+ if ( gdk_gl_drawable_is_double_buffered(gldrawable) ) {
+ gdk_gl_drawable_swap_buffers(gldrawable);
+ } else {
+ glFlush();
+ }
+
+ gdk_gl_drawable_gl_end(gldrawable);
+
+ return TRUE;
+
+}
+
+gboolean glbits_configure(GtkWidget *widget, GdkEventConfigure *event, DisplayWindow *dw) {
+
+ GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
+ GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
+ GLfloat w = widget->allocation.width;
+ GLfloat h = widget->allocation.height;
+
+ /* Set viewport */
+ if ( !gdk_gl_drawable_gl_begin(gldrawable, glcontext) ) {
+ return FALSE;
+ }
+ glViewport(0, 0, w, h);
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_LINE_SMOOTH);
+
+ /* Nudge the projection matrix routines to preserve the aspect ratio */
+ if ( dw->view == DW_ORTHO ) {
+ glbits_set_ortho(dw, w, h);
+ } else {
+ glbits_set_perspective(dw, w, h);
+ }
+
+ gdk_gl_drawable_gl_end(gldrawable);
+
+ return FALSE;
+
+}
+
+void glbits_free_resources(DisplayWindow *dw) {
+
+ if ( dw->gl_use_buffers ) {
+ glDeleteBuffersARB(1, &dw->gl_ref_vertex_buffer);
+ glDeleteBuffersARB(1, &dw->gl_ref_normal_buffer);
+ glDeleteBuffersARB(1, &dw->gl_marker_vertex_buffer);
+ glDeleteBuffersARB(1, &dw->gl_marker_normal_buffer);
+ glDeleteBuffersARB(1, &dw->gl_gen_vertex_buffer);
+ glDeleteBuffersARB(1, &dw->gl_gen_normal_buffer);
+ glDeleteBuffersARB(1, &dw->gl_line_vertex_buffer);
+ } else {
+ free(dw->gl_ref_vertex_array);
+ free(dw->gl_ref_normal_array);
+ free(dw->gl_marker_vertex_array);
+ free(dw->gl_marker_normal_array);
+ free(dw->gl_gen_vertex_array);
+ free(dw->gl_gen_normal_array);
+ free(dw->gl_line_vertex_array);
+ }
+ glDeleteLists(dw->gl_list_id, 1);
+
+}
+
diff --git a/src/glbits.h b/src/glbits.h
new file mode 100644
index 0000000..58520fd
--- /dev/null
+++ b/src/glbits.h
@@ -0,0 +1,31 @@
+/*
+ * glbits.h
+ *
+ * OpenGL bits
+ *
+ * (c) 2007 Thomas White <taw27@cam.ac.uk>
+ *
+ * dtr - Diffraction Tomography Reconstruction
+ *
+ */
+
+#ifndef GLBITS_H
+#define GLBITS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "displaywindow.h"
+
+extern void glbits_prepare(DisplayWindow *dw);
+extern gint glbits_expose(GtkWidget *widget, GdkEventExpose *event, DisplayWindow *dw);
+extern void glbits_set_ortho(DisplayWindow *dw, GLfloat w, GLfloat h);
+extern void glbits_set_perspective(DisplayWindow *dw, GLfloat w, GLfloat h);
+extern gboolean glbits_configure(GtkWidget *widget, GdkEventConfigure *event, DisplayWindow *dw);
+extern void glbits_free_resources(DisplayWindow *dw);
+
+#endif /* GLBITS_H */
+