aboutsummaryrefslogtreecommitdiff
path: root/src/displaywindow.c
diff options
context:
space:
mode:
authortaw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1>2007-10-19 12:16:35 +0000
committertaw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1>2007-10-19 12:16:35 +0000
commit7c4c25f2eda4f0a0780cf2edb087452ceb63f226 (patch)
tree0c2c93d4e6c84b68ba0dd132e0463b32a5312e76 /src/displaywindow.c
parent8b79d6667505aecf510e7b90a727fa1ae0e1fb40 (diff)
Straighten out transformations etc
git-svn-id: svn://cook.msm.cam.ac.uk:745/diff-tomo/dtr@157 bf6ca9ba-c028-0410-8290-897cf20841d1
Diffstat (limited to 'src/displaywindow.c')
-rw-r--r--src/displaywindow.c208
1 files changed, 123 insertions, 85 deletions
diff --git a/src/displaywindow.c b/src/displaywindow.c
index 250f790..d4cb3f7 100644
--- a/src/displaywindow.c
+++ b/src/displaywindow.c
@@ -36,35 +36,20 @@
static void displaywindow_gl_set_ortho(DisplayWindow *dw, GLfloat w, GLfloat h) {
+ GLfloat aspect = w/h;
+
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- if ( w > h ) {
- GLfloat aspect = w/h;
- glOrtho(-aspect*(dw->distance/2.0), aspect*(dw->distance/2.0), -(dw->distance/2.0), (dw->distance/2.0), 1.0, 400.0);
- } else {
- GLfloat aspect = h/w;
- glOrtho(-(dw->distance/2.0), (dw->distance/2.0), -aspect*(dw->distance/2.0), aspect*(dw->distance/2.0), 1.0, 400.0);
- }
+ 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) {
- GLfloat d;
-
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
-
- /* If zoomed a long way out, the model will be moved back rather than
- * changing the projection matrix. This avoids getting a "fisheye" view */
- if ( dw->distance/4.0 < 50.0 ) {
- d = dw->distance/4.0;
- } else {
- d = 50.0;
- }
-
- gluPerspective(d, w/h, 1.0, 400.0);
+ gluPerspective(50.0, w/h, 0.001, 400.0);
glMatrixMode(GL_MODELVIEW);
}
@@ -173,46 +158,30 @@ static gint displaywindow_gl_motion_notify(GtkWidget *widget, GdkEventMotion *ev
} \
}
-#define DRAW_POINTER \
- glBegin(GL_LINES); \
- glNormal3f(1.0, 0.0, 0.0); \
- glVertex3f(50.0, 0.0, 0.0); \
- glVertex3f(-50.0, 0.0, 0.0); \
- glEnd(); \
- glBegin(GL_TRIANGLE_FAN); \
- glNormal3f(1.0, 0.0, 0.0); \
- glVertex3f(50.0, 0.0, 0.0); \
- glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
- glVertex3f(50.0-5.0, 1.0, 1.0); \
- glNormal3f(-2.5/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
- glVertex3f(50.0-5.0, -1.0, 1.0); \
- glNormal3f(-2.5/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1)); \
- glVertex3f(50.0-5.0, -1.0, -1.0); \
- glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1)); \
- glVertex3f(50.0-5.0, 1.0, -1.0); \
- glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
- glVertex3f(50.0-5.0, 1.0, 1.0); \
- glEnd();
-
-#define DRAW_SHORT_POINTER \
+#define DRAW_POINTER_LINE \
glBegin(GL_LINES); \
+ glVertex3f(1.0, 0.0, 0.0); \
glVertex3f(0.0, 0.0, 0.0); \
- glVertex3f(10.0, 0.0, 0.0); \
- glEnd(); \
- glBegin(GL_TRIANGLE_FAN); \
- glNormal3f(1.0, 0.0, 0.0); \
- glVertex3f(10.0, 0.0, 0.0); \
- glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
- glVertex3f(10.0-2.0, 0.2, 0.2); \
- glNormal3f(-2.5/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
- glVertex3f(10.0-2.0, -0.2, 0.2); \
- glNormal3f(-2.5/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1)); \
- glVertex3f(10.0-2.0, -0.2, -0.2); \
- glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1)); \
- glVertex3f(10.0-2.0, 0.2, -0.2); \
- glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
- glVertex3f(10.0-2.0, 0.2, 0.2); \
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_create_list(DisplayWindow *dw) {
@@ -351,8 +320,8 @@ static void displaywindow_gl_create_list(DisplayWindow *dw) {
/* Bounding cube: 100 nm^-1 side length */
if ( dw->cube ) {
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ 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);
@@ -397,26 +366,49 @@ static void displaywindow_gl_create_list(DisplayWindow *dw) {
}
/* 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_SHORT_POINTER
+ 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);
- glPushMatrix();
- glRotatef(90.0, 0.0, 0.0, 1.0);
- DRAW_SHORT_POINTER
+ 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);
- glPushMatrix();
- glRotatef(-90.0, 0.0, 1.0, 0.0);
- DRAW_SHORT_POINTER
+ DRAW_POINTER_HEAD
glPopMatrix();
/* Plot the other reflections */
@@ -530,11 +522,18 @@ static void displaywindow_gl_create_list(DisplayWindow *dw) {
* Since the rotation is about +z, this is already anticlockwise
* when looking down z. */
glRotatef(ctx->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
+ 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();
}
@@ -568,12 +567,11 @@ static gint displaywindow_gl_expose(GtkWidget *widget, GdkEventExpose *event, Di
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[] = { 0.0, 0.0, 100.0, 0.0 };
- GLfloat light0_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
- GLfloat light0_specular[] = { 0.5, 0.5, 0.5, 1.0 };
- GLfloat light1_position[] = { 0.0, 0.0, -100.0, 0.0 };
- GLfloat light1_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
- GLfloat light1_specular[] = { 0.5, 0.5, 0.5, 1.0 };
+ GLfloat light0_position[] = { 50.0, 50.0, 50.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 };
if ( !gdk_gl_drawable_gl_begin(gldrawable, glcontext) ) {
return 0;
@@ -581,33 +579,62 @@ static gint displaywindow_gl_expose(GtkWidget *widget, GdkEventExpose *event, Di
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();
- glTranslatef(dw->x_pos, -dw->y_pos, -100.0);
- /* If zoomed a long way out, move the model back rather than
- * changing the projection matrix. This avoids getting a "fisheye" view */
- if ( dw->distance > 100.0 ) glTranslatef(0.0, 0.0, -(dw->distance-100.0));
- build_rotmatrix(m, dw->view_quat);
- glMultMatrixf(&m[0][0]);
+ glTranslatef(0.0, 0.0, -400.0);
+ glTranslatef(dw->x_pos, -dw->y_pos, 400.0-dw->distance);
/* Set up lighting */
- glEnable(GL_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);
- glEnable(GL_LIGHT1);
- glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
- glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);
+
+ /* The z component of this makes no difference if the projection is orthographic,
+ * but controls zoom when perspective is used */
+ build_rotmatrix(m, dw->view_quat);
+ glMultMatrixf(&m[0][0]);
/* Draw the "measured" reflections */
if ( dw->gl_ref_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, green);
+ 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 ) {
@@ -721,6 +748,7 @@ static gboolean displaywindow_gl_configure(GtkWidget *widget, GdkEventConfigure
}
glViewport(0, 0, w, h);
+ glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -842,6 +870,14 @@ static gint displaywindow_changelines(GtkWidget *widget, DisplayWindow *dw) {
return 0;
}
+static gint displaywindow_changebackground(GtkWidget *widget, DisplayWindow *dw) {
+
+ dw->background = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(widget));
+ displaywindow_update(dw);
+
+ return 0;
+}
+
static gint displaywindow_savecache_response(GtkWidget *widget, gint response, ControlContext *ctx) {
if ( response == GTK_RESPONSE_ACCEPT ) {
@@ -899,6 +935,7 @@ static void displaywindow_addmenubar(DisplayWindow *dw) {
GtkToggleActionEntry toggles[] = {
{ "CubeAction", NULL, "Show 100 nm^-1 _Cube", NULL, NULL, G_CALLBACK(displaywindow_changecube), dw->cube },
{ "LinesAction", NULL, "Show Indexing Lines", NULL, NULL, G_CALLBACK(displaywindow_changelines), dw->lines },
+ { "BackgroundAction", NULL, "Show Coloured Background", NULL, NULL, G_CALLBACK(displaywindow_changebackground), dw->background },
};
guint n_toggles = G_N_ELEMENTS(toggles);
@@ -948,6 +985,7 @@ DisplayWindow *displaywindow_open(ControlContext *ctx) {
dw->ctx = ctx;
dw->cube = TRUE;
dw->lines = FALSE;
+ dw->background = TRUE;
dw->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(dw->window), title);