source: anuga_work/development/anugavis/src/height_quantity.c @ 5267

Last change on this file since 5267 was 5267, checked in by jack, 16 years ago

AnugaVis?: compile the data into openGL display lists.

File size: 4.6 KB
Line 
1#ifdef HAVE_CONFIG_H
2#  include "config.h"
3#endif
4
5#ifdef HAVE_STDLIB_H
6#  include <stdlib.h>
7#endif
8#ifdef HAVE_STRING_H
9#  include <string.h>
10#endif
11#ifdef HAVE_GL_GL_H
12#  include <GL/gl.h>
13#elif HAVE_OPENGL_GL_H
14#  include <OpenGL/gl.h>
15#endif
16#include <netcdf.h>
17#include <SDL.h>
18#include "error.h"
19#include "globals.h"
20#include "height_quantity.h"
21#include "netcdf_util.h"
22#include "xfunctions.h"
23
24static int compileDisplayLists(struct height_quantity_simple *height){
25  int frame;
26  unsigned int vol;
27  unsigned int vertex;
28  int vertIndex;
29  int x[3];
30  int y[3];
31  int z[3];
32  float *heights = xmalloc(sizeof(float)
33                           * anugavis.number_of_points
34                           * height->frames, "compileDisplayLists()");
35  if(heights == NULL)
36    return -1;
37  if(nc_get_var_float_by_name(anugavis.netcdfId,
38                              height->name, heights) != NC_NOERR){
39    free(heights);
40    return -1;
41  }
42
43  for(frame = 0 ; frame < height->frames ; frame++){
44    glNewList(height->displayLists + frame, GL_COMPILE);
45    for(vol = 0 ; vol < anugavis.number_of_volumes ; vol++){
46      glBegin(GL_POLYGON);
47      for(vertex = 0 ; vertex < 3 ; vertex++){ /* Calculate normal */
48        vertIndex = anugavis.volumes[vol*anugavis.number_of_vertices + vertex];
49        x[vertex] = anugavis.x[vertIndex];
50        y[vertex] = anugavis.y[vertIndex];
51        z[vertex] = heights[frame * anugavis.number_of_timesteps + vertIndex];
52      }
53      glNormal3f((y[1] - y[0]) * (z[2] - z[0]) - (z[1] - z[0]) * (y[2] - y[0]),
54                 (z[1] - z[0]) * (x[2] - x[0]) - (x[1] - x[0]) * (z[2] - z[0]),
55                 (x[1] - x[0]) * (y[2] - y[0]) - (y[1] - y[0]) * (x[2] - x[0]));
56      for(vertex = 0 ; vertex < anugavis.number_of_vertices ; vertex++){
57        vertIndex = anugavis.volumes[vol*anugavis.number_of_vertices + vertex];
58        glVertex3f(anugavis.x[vertIndex], anugavis.y[vertIndex],
59                   heights[frame * anugavis.number_of_timesteps + vertIndex]);
60      }
61      glEnd();
62    }
63    glEndList();
64  }
65
66  free(heights);
67  return 0;
68}
69
70static void freeHeightQuantity(struct height_quantity_simple *height){
71  if(height->name != NULL) free(height->name);
72  if(glIsList(height->displayLists) == GL_TRUE)
73    glDeleteLists(height->displayLists, height->frames);
74  free(height);
75}
76
77int AnugaVis_DefineHeightQuantity(const char *name,
78                                  double offset, double scale,
79                                  int red, int green, int blue){
80  struct height_quantity_simple *height;
81  int ncstatus;
82  int ncvarid;
83  int numdims;
84  GLenum glerror;
85  /* Check that it's actually in the NetCDF file */
86  if((ncstatus = nc_inq_varid(anugavis.netcdfId, name, &ncvarid)) != NC_NOERR){
87    AnugaVis_NetCDFError(ncstatus);
88    return -1;
89  }     
90
91  /* Redefining a quantity? */
92  for(height = anugavis.heights ; height != NULL ; height = height->next)
93    if(!strcmp(name, height->name)) break;
94
95  if(height == NULL){ /* Make a new entry. */
96    if((height = xmalloc(sizeof(struct height_quantity_simple),
97                         "AnugaVis_DefineHeightQuantity()")) == NULL)
98      return -1;
99
100    height->name = NULL;
101    height->displayLists = -1;
102
103    if((height->name = xstrdup(name,
104                               "AnugaVis_DefineHeightQuantity()")) == NULL){
105      freeHeightQuantity(height);
106      return -1;
107    }
108
109    /* If the NetCDF variable is 2-dimensional, then it's dynamic. */
110    if((ncstatus = nc_inq_varndims(anugavis.netcdfId,
111                                   ncvarid, &numdims)) != NC_NOERR){
112      AnugaVis_NetCDFError(ncstatus);
113      freeHeightQuantity(height);
114      return -1;
115    }
116
117    height->frames = (numdims == 2) ? anugavis.number_of_timesteps : 1;
118    height->displayLists = glGenLists(height->frames);
119    if((glerror = glGetError()) != GL_NO_ERROR){
120      AnugaVis_OpenGLError(glerror);
121      freeHeightQuantity(height);
122      return -1;
123    }
124
125    if(compileDisplayLists(height) == -1){
126      freeHeightQuantity(height);
127      return -1;
128    }
129
130    height->next = anugavis.heights;
131    anugavis.heights = height;
132  }
133
134  height->offset = offset;
135  height->scale = scale;
136  height->color = SDL_MapRGB(anugavis.screen->format, red, green, blue);
137  return 0;
138}
139
140void AnugaVis_UndefineHeightQuantity(char *name){
141  struct height_quantity_simple *height = anugavis.heights;
142  struct height_quantity_simple *nextHeight;
143  if(height == NULL) return;
144  if(!strcmp(name, height->name)){
145    anugavis.heights = height->next;
146    freeHeightQuantity(height);
147    return;
148  }
149  for(; height != NULL ; height = height->next)
150    if(height->next == NULL) return;
151    if(!strcmp(name, height->next->name)){
152      nextHeight = height->next;
153      height->next = height->next->next;
154      freeHeightQuantity(nextHeight);
155      return;
156    }
157}
Note: See TracBrowser for help on using the repository browser.