tutorial: pressure.c

File pressure.c, 6.7 KB (added by leon, 11 years ago)

Pressure example

Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <assert.h>
5#include <GL/glew.h>
6#include <GL/glut.h>
7
8GLuint program;
9GLuint vbo_vertices;
10GLuint vbo_pressure;
11GLuint ibo_elements;
12GLint attribute_coord2d;
13GLint attribute_pressure;
14
15GLfloat *point;   int points;
16GLuint *triangle; int triangles;
17GLfloat *pressure; 
18
19void read_VTK_pressure(const char *filename)
20{
21  char line[80];
22  int i; FILE *f;
23
24  f = fopen(filename, "r");
25  assert(f);
26
27 
28  while(fgets(line, 80, f))
29    {
30      if (strstr(line, "POINTS"))
31        {
32          float dummy_y;
33          points = atof(line+7);
34          point = malloc(points*2*sizeof(float));
35          pressure = malloc(points*sizeof(float));
36          assert(point != NULL && pressure != NULL);
37          for(i = 0; i < points; ++i)
38            fscanf(f, "%f %f %f", &point[i*2], &dummy_y, &point[i*2+1]);
39        }
40      else if (strstr(line, "POLYGONS"))
41        {
42          triangles = atof(line+9);
43          triangle = malloc(triangles*3*sizeof(GLuint));
44          for (i = 0; i < triangles; ++i)
45            {
46              int n;
47              fscanf(f, "%d %d %d %d", &n, &triangle[i*3],
48                     &triangle[i*3+1], &triangle[i*3+2]);
49              assert( n == 3 );
50            }
51        }
52      else if (strstr(line, "FIELD"))
53        {
54          fgets(line, 80, f); // skip: p 1 27582 float
55          for (i = 0; i < points; ++i)
56            fscanf(f, "%f", &pressure[i]);
57        }
58    }
59  fclose(f);
60  printf("Read %d points for %d triangles for field %s\n",
61         points, triangles, filename);
62}
63               
64     
65
66static const GLchar * vertex_shader[] = {
67  "attribute vec2 coord2d;" // input vertex position
68  "attribute float pressure;" // custom variable along with vertex position
69  "varying float  t;" // communicate between the vertex and the fragment shader
70  "void main()"
71  "{"
72  "  t = (pressure+200.0)/400.0;"
73  "  vec2 moved = coord2d + vec2(-0.7, -0.7);"
74  "  gl_Position = gl_ModelViewProjectionMatrix*vec4(moved, 0.0, 1.0);"
75  "}"
76};
77static const GLchar * fragment_shader[] = {
78  "vec3 Cool = vec3(0, 0, 1);" // Red
79  "vec3 Hot  = vec3(1, 0, 0);" // Blue
80  "varying float t;" // Interpolated by fragment
81  "void main()"
82  "{"
83  "  vec3 color = mix(Cool, Hot, t);"  // use the built-in mix() function
84  "  gl_FragColor = vec4(color, 1.0);" // append alpha channel
85  "}"
86};
87
88void active_vertex_shader_inputs(GLuint prog)
89{
90  char *name;
91  GLint active_attribs, max_length;
92  unsigned i;
93
94  glGetProgramiv(prog, GL_ACTIVE_ATTRIBUTES, &active_attribs);
95  glGetProgramiv(prog, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_length);
96
97  name = malloc(max_length + 1);
98  printf("Active vertex shader inputs:\n");
99  for (i = 0; i < active_attribs; i++) {
100    GLint size;
101    GLenum type;
102   
103    glGetActiveAttrib(prog, i, max_length + 1, NULL,
104                      &size, &type, name);
105    printf("Vertex input attribute %s of type %d is at location %d\n", 
106           name, type, glGetAttribLocation(prog, name));
107  }
108  free(name);
109}
110
111void create_shaders()
112{
113  GLuint v, f;
114
115  v = glCreateShader(GL_VERTEX_SHADER);
116  f = glCreateShader(GL_FRAGMENT_SHADER);
117  glShaderSource(v, 1, vertex_shader, NULL);
118  glShaderSource(f, 1, fragment_shader, NULL);
119  glCompileShader(v);
120  GLint compiled;
121  glGetShaderiv(v, GL_COMPILE_STATUS, &compiled );
122  if ( !compiled ) {
123    GLsizei  maxLength, length;
124    glGetShaderiv( v, GL_INFO_LOG_LENGTH, &maxLength );
125    GLchar* log = malloc(sizeof(GLchar)*(maxLength+1));
126    glGetShaderInfoLog(v,  maxLength, &length, log);
127    printf("Vertex Shader compilation failed: %s\n", log);
128    free(log);
129  }
130  glCompileShader(f);
131  glGetShaderiv(f, GL_COMPILE_STATUS, &compiled );
132  if ( !compiled ) {
133    GLsizei  maxLength, length;
134    glGetShaderiv( f, GL_INFO_LOG_LENGTH, &maxLength );
135    GLchar* log = malloc(sizeof(GLchar)*(maxLength+1));
136    glGetShaderInfoLog(f,  maxLength, &length, log);
137    printf("Fragment Shader compilation failed: %s\n", log);
138    free(log);
139  }
140  program = glCreateProgram();
141  glAttachShader(program, f);
142  glAttachShader(program, v);
143  glLinkProgram(program);
144  GLint linked;
145  glGetProgramiv(program, GL_LINK_STATUS, &linked );
146  if ( !linked ) {
147    GLsizei len;
148    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len );
149    GLchar* log = malloc(sizeof(GLchar)*(len+1));
150    glGetProgramInfoLog(program, len, &len, log );
151    printf("Shader linking failed: %s\n", log);
152    free(log);
153  }
154  glUseProgram(program);
155
156
157  attribute_coord2d = glGetAttribLocation(program, "coord2d");
158  if (attribute_coord2d == -1) {
159    fprintf(stderr, "Could not bind attribute coord2d\n");
160  }
161  glEnableVertexAttribArray(attribute_coord2d);
162
163  attribute_pressure = glGetAttribLocation(program, "pressure");
164  if (attribute_pressure == -1) {
165    fprintf(stderr, "Could not bind attribute pressure\n");
166  }
167  glEnableVertexAttribArray(attribute_pressure); // toggle this
168  active_vertex_shader_inputs(program);
169 
170}
171
172void send_buffers_to_GPU(void)
173{
174  GLuint vertex_array_object;
175  glGenVertexArrays(1, &vertex_array_object);
176  glBindVertexArray(vertex_array_object);
177 
178  glGenBuffers(1, &vbo_vertices);
179  glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
180  glBufferData(GL_ARRAY_BUFFER, points*2*sizeof(GLfloat), point, GL_STATIC_DRAW);
181
182  glGenBuffers(1, &vbo_pressure);
183  glBindBuffer(GL_ARRAY_BUFFER, vbo_pressure);
184  glBufferData(GL_ARRAY_BUFFER, points*sizeof(GLfloat), pressure, GL_STATIC_DRAW);
185
186  glGenBuffers(1, &ibo_elements);
187  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_elements);
188  glBufferData(GL_ELEMENT_ARRAY_BUFFER, triangles*3*sizeof(GLuint),
189               triangle, GL_STATIC_DRAW);
190
191}
192
193
194void display(void)
195{
196  glClear(GL_COLOR_BUFFER_BIT);
197 
198  glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
199  glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, NULL);
200
201  glBindBuffer(GL_ARRAY_BUFFER, vbo_pressure);
202  glVertexAttribPointer(attribute_pressure, 1, GL_FLOAT, GL_FALSE, 0, NULL);
203
204  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_elements);
205  glDrawElements(GL_TRIANGLES, triangles*3, GL_UNSIGNED_INT, 0);
206  glutSwapBuffers();
207}
208
209int main(int argc, char **argv)
210{
211  glutInit(&argc, argv);
212  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
213  glutCreateWindow("GLSL Intro");
214  glutDisplayFunc(display);
215  glewInit();
216  if (!glewIsSupported("GL_VERSION_2_0"))
217   {
218     printf("GLSL not supported\n");
219     exit(EXIT_FAILURE);
220   }
221  glClearColor(0.9,1.0,1.0,1.0);
222  read_VTK_pressure("p_yNormal.vtk");
223  send_buffers_to_GPU();
224  // we don't need this anymore as it is in GPU by now
225  free(point); free(triangle); free(pressure);
226  create_shaders();
227
228  glutMainLoop();
229  return EXIT_SUCCESS;
230}