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 | |
---|
8 | GLuint program; |
---|
9 | GLuint vbo_vertices; |
---|
10 | GLuint vbo_pressure; |
---|
11 | GLuint ibo_elements; |
---|
12 | GLint attribute_coord2d; |
---|
13 | GLint attribute_pressure; |
---|
14 | |
---|
15 | GLfloat *point; int points; |
---|
16 | GLuint *triangle; int triangles; |
---|
17 | GLfloat *pressure; |
---|
18 | |
---|
19 | void 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 | |
---|
66 | static 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 | }; |
---|
77 | static 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 | |
---|
88 | void 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 | |
---|
111 | void 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 | |
---|
172 | void 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 | |
---|
194 | void 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 | |
---|
209 | int 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 | } |
---|