aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortaw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1>2007-12-21 21:36:52 +0000
committertaw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1>2007-12-21 21:36:52 +0000
commit2660887cf21229a888c5b1c02a6f07e653d1a55b (patch)
tree84868e33064cc9a7c61aaceb898971b66986e9b8
parenta956795a03969c5aec307474400be402388c1430 (diff)
Fun with shaders
git-svn-id: svn://cook.msm.cam.ac.uk:745/diff-tomo/dtr@235 bf6ca9ba-c028-0410-8290-897cf20841d1
-rw-r--r--data/Makefile.am2
-rw-r--r--data/light-pp.frag40
-rw-r--r--data/light-pp.vert34
-rw-r--r--src/displaywindow.c29
-rw-r--r--src/displaywindow.h3
-rw-r--r--src/glbits.c80
-rw-r--r--src/glbits.h2
7 files changed, 166 insertions, 24 deletions
diff --git a/data/Makefile.am b/data/Makefile.am
index 717d3e5..2948e73 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,5 +1,5 @@
dtrdir = $(datadir)/dtr
-dtr_DATA = displaywindow.ui
+dtr_DATA = displaywindow.ui light-pp.vert light-pp.frag
iconsdir = $(datadir)/icons/hicolor/scalable/apps
icons_DATA = dtr-tiltaxis.svg dtr-dirax.svg dtr-refine.svg dtr-refineall.svg dtr-quantify.svg
diff --git a/data/light-pp.frag b/data/light-pp.frag
new file mode 100644
index 0000000..c862641
--- /dev/null
+++ b/data/light-pp.frag
@@ -0,0 +1,40 @@
+/*
+ * light-pp.frag
+ *
+ * Lighting per pixel
+ *
+ * (c) 2007 Thomas White <taw27@cam.ac.uk>
+ *
+ * dtr - Diffraction Tomography Reconstruction
+ *
+ */
+
+varying vec4 col_ambi;
+varying vec4 col_diff;
+varying vec4 col_spec;
+varying float shininess;
+
+varying vec3 normal;
+varying vec3 halfvc;
+
+void main() {
+
+ vec4 ambi;
+ vec4 diff;
+ vec4 spec;
+
+ /* Ambient contribution */
+ ambi = col_ambi * gl_LightModel.ambient;
+ ambi += col_ambi * gl_LightSource[0].ambient;
+
+ /* Diffuse contribution */
+ diff = col_diff * clamp(dot( vec3(normalize(gl_LightSource[0].position)), normal ), 0.0, 1.0);
+
+ /* Specular contribution */
+ spec = col_spec * pow(dot( vec3(normal), halfvc ), shininess);
+
+ gl_FragColor = ambi + diff + spec;
+ gl_FragColor.a = 1.0;
+
+}
+
diff --git a/data/light-pp.vert b/data/light-pp.vert
new file mode 100644
index 0000000..02ff444
--- /dev/null
+++ b/data/light-pp.vert
@@ -0,0 +1,34 @@
+/*
+ * light-pp.vert
+ *
+ * Lighting per pixel
+ *
+ * (c) 2007 Thomas White <taw27@cam.ac.uk>
+ *
+ * dtr - Diffraction Tomography Reconstruction
+ *
+ */
+
+varying vec4 col_ambi;
+varying vec4 col_diff;
+varying vec4 col_spec;
+varying float shininess;
+
+varying vec3 normal;
+varying vec3 halfvc;
+
+void main() {
+
+ normal = normalize(gl_NormalMatrix * gl_Normal);
+ halfvc = vec3(gl_LightSource[0].halfVector);
+
+ col_ambi = gl_FrontMaterial.ambient;
+ col_diff = gl_FrontMaterial.diffuse;
+ col_spec = gl_FrontMaterial.specular;
+
+ shininess = gl_FrontMaterial.shininess;
+
+ gl_Position = ftransform();
+
+}
+
diff --git a/src/displaywindow.c b/src/displaywindow.c
index 46b4822..4f30a3d 100644
--- a/src/displaywindow.c
+++ b/src/displaywindow.c
@@ -111,28 +111,7 @@ static gint displaywindow_gl_motion_notify(GtkWidget *widget, GdkEventMotion *ev
}
-static gint displaywindow_gl_realise(GtkWidget *widget, 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;
-
- if ( !gdk_gl_drawable_gl_begin(gldrawable, glcontext) ) {
- return 0;
- }
-
- glbits_set_ortho(dw, w, h);
- glbits_prepare(dw);
-
- gdk_gl_drawable_gl_end(gldrawable);
-
- return 0;
-
-}
-
static gint displaywindow_closedown(GtkWidget *widget, DisplayWindow *dw) {
- glbits_free_resources(dw);
gtk_exit(0);
return 0;
}
@@ -367,6 +346,11 @@ static gint displaywindow_refinestack(GtkWidget *widget, DisplayWindow *dw) {
return 0;
}
+static gint displaywindow_gl_destroyed(GtkWidget *widget, DisplayWindow *dw) {
+ glbits_final_free_resources(dw);
+ return 0;
+}
+
static gint displaywindow_extract(GtkWidget *widget, DisplayWindow *dw) {
GtkWidget *d;
@@ -612,10 +596,11 @@ DisplayWindow *displaywindow_open(ControlContext *ctx) {
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(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), "realize", G_CALLBACK(glbits_realise), 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);
+ g_signal_connect(GTK_OBJECT(dw->drawing_area), "destroy", G_CALLBACK(displaywindow_gl_destroyed), dw);
dw->stack = imagedisplay_new_nowindow(ctx->images->images[dw->cur_image], IMAGEDISPLAY_SHOW_TILT_AXIS | IMAGEDISPLAY_SHOW_CENTRE, NULL, NULL, NULL);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dw->stack->vbox, gtk_label_new("Image Stack"));
diff --git a/src/displaywindow.h b/src/displaywindow.h
index 86d2645..baab13d 100644
--- a/src/displaywindow.h
+++ b/src/displaywindow.h
@@ -64,6 +64,9 @@ typedef struct dw_struct {
GLuint gl_line_vertex_buffer; /* Indexing line stuff */
GLfloat *gl_line_vertex_array;
GLsizei gl_line_num_vertices;
+ GLhandleARB gl_vshader_lightpp;
+ GLhandleARB gl_fshader_lightpp;
+ GLhandleARB gl_program_lightpp;
/* Display parameters */
DisplayWindowView view;
diff --git a/src/glbits.c b/src/glbits.c
index 194a919..9a7fca5 100644
--- a/src/glbits.c
+++ b/src/glbits.c
@@ -28,7 +28,53 @@
#include "reflections.h"
#include "image.h"
-#define BLOB_BITS 5
+/* Utility function to load and compile a shader, checking the info log */
+static GLhandleARB glbits_load_shader(const char *filename, GLenum type) {
+
+ GLhandleARB shader;
+ char text[4096];
+ size_t len;
+ FILE *fh;
+ int l;
+
+ fh = fopen(filename, "r");
+ len = fread(text, 1, 4095, fh);
+ fclose(fh);
+ text[len] = '\0';
+ const GLcharARB *source = text;
+ shader = glCreateShaderObjectARB(type);
+ glShaderSourceARB(shader, 1, &source, NULL);
+ glCompileShaderARB(shader);
+ glGetInfoLogARB(shader, 4095, &l, text);
+ if ( l > 0 ) {
+ printf("%s\n", text); fflush(stdout);
+ }
+
+ return shader;
+
+}
+
+static void glbits_load_shaders(DisplayWindow *dw) {
+
+ dw->gl_vshader_lightpp = glbits_load_shader(DATADIR"/dtr/light-pp.vert", GL_VERTEX_SHADER_ARB);
+ dw->gl_fshader_lightpp = glbits_load_shader(DATADIR"/dtr/light-pp.frag", GL_FRAGMENT_SHADER_ARB);
+
+ dw->gl_program_lightpp = glCreateProgramObjectARB();
+ glAttachObjectARB(dw->gl_program_lightpp, dw->gl_vshader_lightpp);
+ glAttachObjectARB(dw->gl_program_lightpp, dw->gl_fshader_lightpp);
+ glLinkProgramARB(dw->gl_program_lightpp);
+
+}
+
+static void glbits_delete_shaders(DisplayWindow *dw) {
+
+ glDetachObjectARB(dw->gl_program_lightpp, dw->gl_fshader_lightpp);
+ glDeleteObjectARB(dw->gl_fshader_lightpp);
+ glDeleteObjectARB(dw->gl_program_lightpp);
+
+}
+
+#define BLOB_BITS 7
#define VERTICES_IN_A_BLOB 4*BLOB_BITS*BLOB_BITS*2
#define ADD_VERTEX \
vertices[3*i + 0] = reflection->x/1e9 + size*xv; \
@@ -704,6 +750,7 @@ gint glbits_expose(GtkWidget *widget, GdkEventExpose *event, DisplayWindow *dw)
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);
+ glUseProgramObjectARB(dw->gl_program_lightpp);
if ( dw->gl_use_buffers ) {
glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_gen_vertex_buffer);
glVertexPointer(3, GL_FLOAT, 0, NULL);
@@ -716,6 +763,7 @@ gint glbits_expose(GtkWidget *widget, GdkEventExpose *event, DisplayWindow *dw)
glNormalPointer(GL_FLOAT, 0, dw->gl_gen_normal_array);
glDrawArrays(GL_QUADS, 0, dw->gl_gen_num_vertices);
}
+ glUseProgramObjectARB(0);
glDisableClientState(GL_NORMAL_ARRAY);
glPopClientAttrib();
}
@@ -812,3 +860,33 @@ void glbits_free_resources(DisplayWindow *dw) {
}
+void glbits_final_free_resources(DisplayWindow *dw) {
+ glbits_free_resources(dw);
+ glbits_delete_shaders(dw);
+}
+
+static void glbits_first_prepare(DisplayWindow *dw) {
+ glbits_prepare(dw);
+ glbits_load_shaders(dw);
+}
+
+gint glbits_realise(GtkWidget *widget, 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;
+
+ if ( !gdk_gl_drawable_gl_begin(gldrawable, glcontext) ) {
+ return 0;
+ }
+
+ glbits_set_ortho(dw, w, h);
+ glbits_first_prepare(dw);
+
+ gdk_gl_drawable_gl_end(gldrawable);
+
+ return 0;
+
+}
+
diff --git a/src/glbits.h b/src/glbits.h
index 58520fd..a958217 100644
--- a/src/glbits.h
+++ b/src/glbits.h
@@ -26,6 +26,8 @@ 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);
+extern void glbits_final_free_resources(DisplayWindow *dw);
+extern gint glbits_realise(GtkWidget *widget, DisplayWindow *dw);
#endif /* GLBITS_H */