diff options
author | taw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1> | 2007-12-21 21:36:52 +0000 |
---|---|---|
committer | taw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1> | 2007-12-21 21:36:52 +0000 |
commit | 2660887cf21229a888c5b1c02a6f07e653d1a55b (patch) | |
tree | 84868e33064cc9a7c61aaceb898971b66986e9b8 | |
parent | a956795a03969c5aec307474400be402388c1430 (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.am | 2 | ||||
-rw-r--r-- | data/light-pp.frag | 40 | ||||
-rw-r--r-- | data/light-pp.vert | 34 | ||||
-rw-r--r-- | src/displaywindow.c | 29 | ||||
-rw-r--r-- | src/displaywindow.h | 3 | ||||
-rw-r--r-- | src/glbits.c | 80 | ||||
-rw-r--r-- | src/glbits.h | 2 |
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 */ |