From 7c4c25f2eda4f0a0780cf2edb087452ceb63f226 Mon Sep 17 00:00:00 2001 From: taw27 Date: Fri, 19 Oct 2007 12:16:35 +0000 Subject: Straighten out transformations etc git-svn-id: svn://cook.msm.cam.ac.uk:745/diff-tomo/dtr@157 bf6ca9ba-c028-0410-8290-897cf20841d1 --- data/displaywindow.ui | 1 + src/displaywindow.c | 208 +++++++++++++++++++++++++++++--------------------- src/displaywindow.h | 1 + 3 files changed, 125 insertions(+), 85 deletions(-) diff --git a/data/displaywindow.ui b/data/displaywindow.ui index 86da6f7..2c369b9 100644 --- a/data/displaywindow.ui +++ b/data/displaywindow.ui @@ -11,6 +11,7 @@ + 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); diff --git a/src/displaywindow.h b/src/displaywindow.h index 555cb5b..6857dc9 100644 --- a/src/displaywindow.h +++ b/src/displaywindow.h @@ -65,6 +65,7 @@ typedef struct dw_struct { float view_quat[4]; int cube; int lines; + int background; float x_start; float y_start; -- cgit v1.2.3