aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortaw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1>2007-09-01 11:15:58 +0000
committertaw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1>2007-09-01 11:15:58 +0000
commitb119052d89113e9b2cb69ff2377571e8d0564b10 (patch)
tree9f16d015723e18c65659557d46f47e99f2d58287
parent9211fbeed3b968f3364dcb42f4b3b48b78e4ad0b (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.h21
-rw-r--r--src/displaywindow.c215
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);