diff options
author | taw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1> | 2007-09-01 11:15:58 +0000 |
---|---|---|
committer | taw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1> | 2007-09-01 11:15:58 +0000 |
commit | b119052d89113e9b2cb69ff2377571e8d0564b10 (patch) | |
tree | 9f16d015723e18c65659557d46f47e99f2d58287 | |
parent | 9211fbeed3b968f3364dcb42f4b3b48b78e4ad0b (diff) |
Use buffer objects for even faster rendering
git-svn-id: svn://cook.msm.cam.ac.uk:745/diff-tomo/dtr@104 bf6ca9ba-c028-0410-8290-897cf20841d1
-rw-r--r-- | src/control.h | 21 | ||||
-rw-r--r-- | src/displaywindow.c | 215 |
2 files changed, 127 insertions, 109 deletions
diff --git a/src/control.h b/src/control.h index 69d57f6..6fab72d 100644 --- a/src/control.h +++ b/src/control.h @@ -117,18 +117,23 @@ typedef struct cctx_struct { GtkWidget *checkbox_prealign; GtkWidget *checkbox_savecache; GLuint gl_list_id; -// GLuint gl_ref_buffer; -// GLuint gl_element_buffer; - GLfloat *gl_ref_vertex_array; - GLuint *gl_ref_element_array; + + GLuint gl_ref_vertex_buffer; + GLuint gl_ref_element_buffer; +// GLfloat *gl_ref_vertex_array; +// GLuint *gl_ref_element_array; GLsizei gl_ref_num_vertices; - GLfloat *gl_marker_vertex_array; - GLuint *gl_marker_element_array; + GLuint gl_marker_vertex_buffer; + GLuint gl_marker_element_buffer; +// GLfloat *gl_marker_vertex_array; +// GLuint *gl_marker_element_array; GLsizei gl_marker_num_vertices; - GLfloat *gl_gen_vertex_array; - GLuint *gl_gen_element_array; + GLuint gl_gen_vertex_buffer; + GLuint gl_gen_element_buffer; +// GLfloat *gl_gen_vertex_array; +// GLuint *gl_gen_element_array; GLsizei gl_gen_num_vertices; } ControlContext; diff --git a/src/displaywindow.c b/src/displaywindow.c index 762ab0f..8264a5b 100644 --- a/src/displaywindow.c +++ b/src/displaywindow.c @@ -99,10 +99,10 @@ static void displaywindow_gl_set_ortho(GLfloat w, GLfloat h) { glLoadIdentity(); if ( w > h ) { GLfloat aspect = w/h; - glOrtho(-aspect*(displaywindow_distance/2), aspect*(displaywindow_distance/2), -(displaywindow_distance/2), (displaywindow_distance/2), 2.0, 1000.0); + glOrtho(-aspect*(displaywindow_distance/2), aspect*(displaywindow_distance/2), -(displaywindow_distance/2), (displaywindow_distance/2), 0.01, 1000.0); } else { GLfloat aspect = h/w; - glOrtho(-(displaywindow_distance/2), (displaywindow_distance/2), -aspect*(displaywindow_distance/2), aspect*(displaywindow_distance/2), 2.0, 1000.0); + glOrtho(-(displaywindow_distance/2), (displaywindow_distance/2), -aspect*(displaywindow_distance/2), aspect*(displaywindow_distance/2), 0.01, 1000.0); } glMatrixMode(GL_MODELVIEW); @@ -240,64 +240,43 @@ static gint displaywindow_gl_motion_notify(GtkWidget *widget, GdkEventMotion *ev return TRUE; } -#define VERTICES_IN_A_BLOB 24 -#define DRAW_BLOB \ - GLfloat d; \ - GLfloat size=0.2; \ - for ( d = -1.4*size; d<= 1.4*size; d+=2.8*size-0.001 ) { /* Precision issues.. */ \ - vertices[3*i + 0] = reflection->x/1e9 - size; \ - vertices[3*i + 1] = reflection->y/1e9 - size; \ - vertices[3*i + 2] = reflection->z/1e9; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9 - size; \ - vertices[3*i + 1] = reflection->y/1e9 + size; \ - vertices[3*i + 2] = reflection->z/1e9; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9; \ - vertices[3*i + 1] = reflection->y/1e9; \ - vertices[3*i + 2] = reflection->z/1e9 + d; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9 - size; \ - vertices[3*i + 1] = reflection->y/1e9 + size; \ - vertices[3*i + 2] = reflection->z/1e9; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9 + size; \ - vertices[3*i + 1] = reflection->y/1e9 + size; \ - vertices[3*i + 2] = reflection->z/1e9; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9; \ - vertices[3*i + 1] = reflection->y/1e9; \ - vertices[3*i + 2] = reflection->z/1e9 + d; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9 + size; \ - vertices[3*i + 1] = reflection->y/1e9 + size; \ - vertices[3*i + 2] = reflection->z/1e9; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9 + size; \ - vertices[3*i + 1] = reflection->y/1e9 - size; \ - vertices[3*i + 2] = reflection->z/1e9; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9; \ - vertices[3*i + 1] = reflection->y/1e9; \ - vertices[3*i + 2] = reflection->z/1e9 + d; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9 + size; \ - vertices[3*i + 1] = reflection->y/1e9 - size; \ - vertices[3*i + 2] = reflection->z/1e9; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9 - size; \ - vertices[3*i + 1] = reflection->y/1e9 - size; \ - vertices[3*i + 2] = reflection->z/1e9; \ - elements[i] = i; i++; \ - vertices[3*i + 0] = reflection->x/1e9; \ - vertices[3*i + 1] = reflection->y/1e9; \ - vertices[3*i + 2] = reflection->z/1e9 + d; \ - elements[i] = i; i++; \ - } +#define VERTICES_IN_A_BLOB 4*10*10 +#define ADD_VERTEX \ + vertices[3*i + 0] = reflection->x/1e9 + xv; \ + vertices[3*i + 1] = reflection->y/1e9 + yv; \ + vertices[3*i + 2] = reflection->z/1e9 + zv; \ + elements[i] = i; i++; + +#define DRAW_BLOB \ + double theta, phi; \ + double steps = 10; \ + double size = 0.2; \ + for ( theta = 0.0; theta<2*M_PI; theta+=2*M_PI/steps ) { \ + for ( phi = 0.0; phi<M_PI; phi+=M_PI/steps ) { \ + GLfloat xv, yv, zv; \ + xv = size*sin(phi) + size*cos(theta); \ + yv = size*cos(phi); \ + zv = size*sin(theta); \ + ADD_VERTEX \ + xv = size*sin(phi+M_PI/steps) + size*cos(theta);\ + yv = size*cos(phi+M_PI/steps); \ + zv = size*sin(theta); \ + ADD_VERTEX \ + xv = size*sin(phi+M_PI/steps) + size*cos(theta+2*M_PI/steps);\ + yv = size*cos(phi+M_PI/steps); \ + zv = size*sin(theta+2*M_PI/steps); \ + ADD_VERTEX \ + xv = size*sin(phi) + size*cos(theta+2*M_PI/steps);\ + yv = size*cos(phi); \ + zv = size*sin(theta+2*M_PI/steps); \ + ADD_VERTEX \ + } \ + } static void displaywindow_gl_create_list(ControlContext *ctx) { - GLfloat blue[] = { 0.0, 0.0, 1.0, 1.0 }; + GLfloat blue[] = { 0.0, 0.0, 0.2, 1.0 }; + GLfloat blue_spec[] = { 0.0, 0.0, 1.0, 1.0 }; GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 }; GLfloat yellow[] = { 1.0, 1.0, 0.0, 1.0 }; GLfloat yellow_glass[] = { 1.0, 1.0, 0.0, 000.1 }; @@ -307,12 +286,9 @@ static void displaywindow_gl_create_list(ControlContext *ctx) { GLfloat *vertices; GLuint *elements; - /* Put the measured reflections in a buffer object */ -// glGenBuffers(1, &ctx->gl_ref_buffer); -// glGenBuffers(1, &ctx->gl_element_buffer); -// glBindBuffer(GL_ARRAY_BUFFER, ctx->gl_ref_buffer); - - /* Count the number of "normal" reflections */ + /* "Measured" reflections */ + glGenBuffersARB(1, &ctx->gl_ref_vertex_buffer); + glGenBuffersARB(1, &ctx->gl_ref_element_buffer); reflection = ctx->reflectionctx->reflections; i = 0; do { @@ -334,14 +310,20 @@ static void displaywindow_gl_create_list(ControlContext *ctx) { } reflection = reflection->next; } while ( reflection != NULL ); - ctx->gl_ref_vertex_array = vertices; -// glBufferData(GL_ARRAY_BUFFER, 3*ctx->gl_ref_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW); -// free(vertices); - ctx->gl_ref_element_array = elements; -// glBufferData(GL_ARRAY_BUFFER, ctx->gl_ref_num_vertices*sizeof(GLushort), elements, GL_STATIC_DRAW); -// free(elements); - - /* Count the number of marker "reflections" */ +// ctx->gl_ref_vertex_array = vertices; + glBindBufferARB(GL_ARRAY_BUFFER, ctx->gl_ref_vertex_buffer); + glBufferDataARB(GL_ARRAY_BUFFER, 3*ctx->gl_ref_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW); + free(vertices); +// ctx->gl_ref_element_array = elements; + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ctx->gl_ref_element_buffer); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, ctx->gl_ref_num_vertices*sizeof(GLuint), elements, GL_STATIC_DRAW); + free(elements); + glBindBufferARB(GL_ARRAY_BUFFER, NULL); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, NULL); + + /* Marker "reflections" */ + glGenBuffersARB(1, &ctx->gl_marker_vertex_buffer); + glGenBuffersARB(1, &ctx->gl_marker_element_buffer); reflection = ctx->reflectionctx->reflections; i = 0; do { @@ -359,14 +341,18 @@ static void displaywindow_gl_create_list(ControlContext *ctx) { } reflection = reflection->next; } while ( reflection != NULL ); - ctx->gl_marker_vertex_array = vertices; -// glBufferData(GL_ARRAY_BUFFER, 3*ctx->gl_ref_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW); -// free(vertices); - ctx->gl_marker_element_array = elements; -// glBufferData(GL_ARRAY_BUFFER, ctx->gl_ref_num_vertices*sizeof(GLushort), elements, GL_STATIC_DRAW); -// free(elements); - - /* Count the number of generated reflections */ +// ctx->gl_marker_vertex_array = vertices; + glBindBufferARB(GL_ARRAY_BUFFER, ctx->gl_marker_vertex_buffer); + glBufferDataARB(GL_ARRAY_BUFFER, 3*ctx->gl_marker_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW); + free(vertices); +// ctx->gl_marker_element_array = elements; + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ctx->gl_marker_element_buffer); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, ctx->gl_marker_num_vertices*sizeof(GLuint), elements, GL_STATIC_DRAW); + free(elements); + + /* Generated reflections */ + glGenBuffersARB(1, &ctx->gl_gen_vertex_buffer); + glGenBuffersARB(1, &ctx->gl_gen_element_buffer); reflection = ctx->reflectionctx->reflections; i = 0; do { @@ -384,12 +370,14 @@ static void displaywindow_gl_create_list(ControlContext *ctx) { } reflection = reflection->next; } while ( reflection != NULL ); - ctx->gl_gen_vertex_array = vertices; -// glBufferData(GL_ARRAY_BUFFER, 3*ctx->gl_ref_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW); -// free(vertices); - ctx->gl_gen_element_array = elements; -// glBufferData(GL_ARRAY_BUFFER, ctx->gl_ref_num_vertices*sizeof(GLushort), elements, GL_STATIC_DRAW); -// free(elements); +// ctx->gl_gen_vertex_array = vertices; + glBindBufferARB(GL_ARRAY_BUFFER, ctx->gl_gen_vertex_buffer); + glBufferDataARB(GL_ARRAY_BUFFER, 3*ctx->gl_gen_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW); + free(vertices); +// ctx->gl_gen_element_array = elements; + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ctx->gl_gen_element_buffer); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, ctx->gl_gen_num_vertices*sizeof(GLuint), elements, GL_STATIC_DRAW); + free(elements); ctx->gl_list_id = glGenLists(1); glNewList(ctx->gl_list_id, GL_COMPILE); @@ -445,10 +433,14 @@ static void displaywindow_gl_create_list(ControlContext *ctx) { if ( reflection->type == REFLECTION_CENTRAL ) { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blue_spec); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0); glPushMatrix(); glTranslatef(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9); gluSphere(quadric, 0.2, 32, 32); glPopMatrix(); + + break; /* Assume there's only one. */ } @@ -459,7 +451,7 @@ static void displaywindow_gl_create_list(ControlContext *ctx) { /* If this is an iterative prediction-refinement reconstruction, draw the unit cell */ if ( ctx->rmode == RECONSTRUCTION_PREDICTION ) { glBegin(GL_LINE_STRIP); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); glVertex3f(0.0, 0.0, 0.0); glVertex3f(ctx->reflectionctx->basis->a.x/1e9, ctx->reflectionctx->basis->a.y/1e9, ctx->reflectionctx->basis->a.z/1e9); glVertex3f(ctx->reflectionctx->basis->a.x/1e9 + ctx->reflectionctx->basis->b.x/1e9, @@ -520,7 +512,6 @@ static gint displaywindow_gl_expose(GtkWidget *widget, GdkEventExpose *event, Co GdkGLContext *glcontext = gtk_widget_get_gl_context(widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget); float m[4][4]; -// GLfloat fog_density = 0.03; 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 }; @@ -528,18 +519,20 @@ static gint displaywindow_gl_expose(GtkWidget *widget, GdkEventExpose *event, Co GLfloat light1_diffuse[] = { 0.8, 0.8, 0.8, 1.0 }; GLfloat light1_specular[] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 }; - GLfloat blue[] = { 0.0, 0.0, 1.0, 1.0 }; - GLfloat gold[] = { 0.7, 0.7, 0.0, 1.0 }; + GLfloat blue[] = { 0.0, 0.0, 0.2, 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.7, 0.7, 0.0, 1.0 }; if ( !gdk_gl_drawable_gl_begin(gldrawable, glcontext) ) { return 0; } - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glEnable(GL_DEPTH_TEST); -// glEnable(GL_FOG); -// glFogfv(GL_FOG_DENSITY, &fog_density); + glEnable(GL_FOG); + glFogf(GL_FOG_DENSITY, 0.005); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -563,25 +556,47 @@ static gint displaywindow_gl_expose(GtkWidget *widget, GdkEventExpose *event, Co glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glEnableClientState(GL_VERTEX_ARRAY); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green); - glVertexPointer(3, GL_FLOAT, 0, ctx->gl_ref_vertex_array); - glDrawRangeElements(GL_POINTS, 0, ctx->gl_ref_num_vertices, ctx->gl_ref_num_vertices, GL_UNSIGNED_INT, ctx->gl_ref_element_array); + glBindBufferARB(GL_ARRAY_BUFFER, ctx->gl_ref_vertex_buffer); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ctx->gl_ref_element_buffer); +// glVertexPointer(3, GL_FLOAT, 0, ctx->gl_ref_vertex_array); + glVertexPointer(3, GL_FLOAT, 0, NULL); +// glDrawRangeElements(GL_POINTS, 0, ctx->gl_ref_num_vertices, ctx->gl_ref_num_vertices, GL_UNSIGNED_INT, ctx->gl_ref_element_array); + glDrawRangeElements(GL_POINTS, 0, ctx->gl_ref_num_vertices, ctx->gl_ref_num_vertices, GL_UNSIGNED_INT, NULL); glPopClientAttrib(); +/// glBindBufferARB(GL_ARRAY_BUFFER, NULL); +/// glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, NULL); /* Draw marker points */ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glEnableClientState(GL_VERTEX_ARRAY); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue); - glVertexPointer(3, GL_FLOAT, 0, ctx->gl_marker_vertex_array); - glDrawRangeElements(GL_TRIANGLES, 0, ctx->gl_marker_num_vertices, ctx->gl_marker_num_vertices, GL_UNSIGNED_INT, ctx->gl_marker_element_array); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blue_spec); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0); + glBindBufferARB(GL_ARRAY_BUFFER, ctx->gl_marker_vertex_buffer); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ctx->gl_marker_element_buffer); +// glVertexPointer(3, GL_FLOAT, 0, ctx->gl_marker_vertex_array); + glVertexPointer(3, GL_FLOAT, 0, NULL); +// glDrawRangeElements(GL_QUADS, 0, ctx->gl_marker_num_vertices, ctx->gl_marker_num_vertices, GL_UNSIGNED_INT, ctx->gl_marker_element_array); + glDrawRangeElements(GL_QUADS, 0, ctx->gl_marker_num_vertices, ctx->gl_marker_num_vertices, GL_UNSIGNED_INT, NULL); glPopClientAttrib(); +/// glBindBufferARB(GL_ARRAY_BUFFER, NULL); +/// glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, NULL); /* Draw generated reflections */ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glEnableClientState(GL_VERTEX_ARRAY); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, gold); - glVertexPointer(3, GL_FLOAT, 0, ctx->gl_gen_vertex_array); - glDrawRangeElements(GL_TRIANGLES, 0, ctx->gl_gen_num_vertices, ctx->gl_gen_num_vertices, GL_UNSIGNED_INT, ctx->gl_gen_element_array); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gold_spec); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0); + glBindBufferARB(GL_ARRAY_BUFFER, ctx->gl_gen_vertex_buffer); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ctx->gl_gen_element_buffer); +// glVertexPointer(3, GL_FLOAT, 0, ctx->gl_gen_vertex_array); + glVertexPointer(3, GL_FLOAT, 0, NULL); +// glDrawRangeElements(GL_QUADS, 0, ctx->gl_gen_num_vertices, ctx->gl_gen_num_vertices, GL_UNSIGNED_INT, ctx->gl_gen_element_array); + glDrawRangeElements(GL_QUADS, 0, ctx->gl_gen_num_vertices, ctx->gl_gen_num_vertices, GL_UNSIGNED_INT, NULL); glPopClientAttrib(); + glBindBufferARB(GL_ARRAY_BUFFER, NULL); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, NULL); /* Draw everything else */ glCallList(ctx->gl_list_id); @@ -608,9 +623,7 @@ static gint displaywindow_gl_realise(GtkWidget *widget, ControlContext *ctx) { if ( !gdk_gl_drawable_gl_begin(gldrawable, glcontext) ) { return 0; } - - glClearColor(0.002, 0.0, 0.1, 1.0); - glClearDepth(1.0); + displaywindow_gl_set_ortho(w, h); displaywindow_gl_create_list(ctx); |